@circle-fin/app-kit 1.13.0 → 1.14.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/swap.mjs CHANGED
@@ -28,7 +28,7 @@ if (typeof window !== 'undefined' && typeof window.Buffer === 'undefined') {
28
28
 
29
29
 
30
30
  import { z } from 'zod';
31
- import 'pino';
31
+ import pino from 'pino';
32
32
  import { hexlify, hexZeroPad } from '@ethersproject/bytes';
33
33
  import '@ethersproject/abi';
34
34
  import { getAddress } from '@ethersproject/address';
@@ -3537,8 +3537,45 @@ var EarnChain;
3537
3537
  * This program handles minting operations for Gateway transactions
3538
3538
  * on Solana devnet.
3539
3539
  */ const GATEWAY_MINTER_SOLANA_DEVNET = 'GATEmKK2ECL1brEngQZWCgMWPbvrEYqsV6u29dAaHavr';
3540
- /** TokenMessengerWithFees address shared by enabled EVM mainnet sources. */ const TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET = '0x71f54F818671cD0D7ea140Da213e5C8b5C92a408';
3541
- /** TokenMessengerWithFees address shared by enabled EVM testnet sources. */ const TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET = '0x8745D906D67C346E5eb1aEEED38Eb87F34DF0C0A';
3540
+ /**
3541
+ * The `TokenMessengerWithFees` proxy contract address for EVM mainnet networks
3542
+ * (all chains except Edge).
3543
+ *
3544
+ * Deployed at a CREATE3-derived address; identical across all mainnet EVM
3545
+ * source chains. Present on any chain that supports the prepaid FORWARD path
3546
+ * via `depositForBurnWithHookAndFees`.
3547
+ */ const TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET = '0x71f54F818671cD0D7ea140Da213e5C8b5C92a408';
3548
+ /**
3549
+ * The `TokenMessengerWithFees` proxy contract address for EVM testnet networks.
3550
+ *
3551
+ * Identical across all testnet EVM source chains. Present on any testnet chain
3552
+ * that supports the prepaid FORWARD path via `depositForBurnWithHookAndFees`.
3553
+ */ const TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET = '0x8745D906D67C346E5eb1aEEED38Eb87F34DF0C0A';
3554
+ /**
3555
+ * The `DepositForHandler` proxy contract address for EVM mainnet networks.
3556
+ *
3557
+ * The handler the GenericExecutor calls on a fast-deposit destination chain to
3558
+ * run a cross-chain deposit into the GatewayWallet. Deployed at the same
3559
+ * address across all mainnet EVM destination chains.
3560
+ */ const DEPOSIT_FOR_HANDLER_EVM_MAINNET = '0x16529813203f77E036576666336554a1210dce4D';
3561
+ /**
3562
+ * The `DepositForHandler` proxy contract address for EVM testnet networks.
3563
+ *
3564
+ * Identical across all testnet EVM destination chains.
3565
+ */ const DEPOSIT_FOR_HANDLER_EVM_TESTNET = '0xD05E7D2E7d30b92c5F17d7d0fC575fce231F1A48';
3566
+ /**
3567
+ * The `GenericExecutor` proxy contract address for EVM mainnet networks.
3568
+ *
3569
+ * The GenericExecutor is the `mintRecipient` and `destinationCaller` on the
3570
+ * destination chain for the CCTP v2 prepaid FORWARD path. It receives the CCTP
3571
+ * mint and calls the `DepositForHandler` to complete the fast deposit.
3572
+ * Deployed at the same address across all mainnet EVM destination chains.
3573
+ */ const GENERIC_EXECUTOR_EVM_MAINNET = '0xFa7be2f04F3Ad4ca969260729c6d45B5625984A7';
3574
+ /**
3575
+ * The `GenericExecutor` proxy contract address for EVM testnet networks.
3576
+ *
3577
+ * Identical across all testnet EVM destination chains.
3578
+ */ const GENERIC_EXECUTOR_EVM_TESTNET = '0xEdC81040756AcCfF070c21D37b265b9D0b5Ba45e';
3542
3579
 
3543
3580
  /**
3544
3581
  * Arc Testnet chain definition
@@ -3597,9 +3634,8 @@ var EarnChain;
3597
3634
  v1: {
3598
3635
  wallet: GATEWAY_WALLET_EVM_TESTNET,
3599
3636
  minter: GATEWAY_MINTER_EVM_TESTNET,
3600
- // DepositForHandler the GenericExecutor calls to run a fast cross-chain
3601
- // deposit into the GatewayWallet above.
3602
- depositForHandler: '0xD05E7D2E7d30b92c5F17d7d0fC575fce231F1A48'
3637
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_TESTNET,
3638
+ genericExecutor: GENERIC_EXECUTOR_EVM_TESTNET
3603
3639
  }
3604
3640
  },
3605
3641
  forwarderSupported: {
@@ -3794,7 +3830,9 @@ var EarnChain;
3794
3830
  contracts: {
3795
3831
  v1: {
3796
3832
  wallet: GATEWAY_WALLET_EVM_MAINNET,
3797
- minter: GATEWAY_MINTER_EVM_MAINNET
3833
+ minter: GATEWAY_MINTER_EVM_MAINNET,
3834
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_MAINNET,
3835
+ genericExecutor: GENERIC_EXECUTOR_EVM_MAINNET
3798
3836
  }
3799
3837
  },
3800
3838
  forwarderSupported: {
@@ -3858,7 +3896,9 @@ var EarnChain;
3858
3896
  contracts: {
3859
3897
  v1: {
3860
3898
  wallet: GATEWAY_WALLET_EVM_TESTNET,
3861
- minter: GATEWAY_MINTER_EVM_TESTNET
3899
+ minter: GATEWAY_MINTER_EVM_TESTNET,
3900
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_TESTNET,
3901
+ genericExecutor: GENERIC_EXECUTOR_EVM_TESTNET
3862
3902
  }
3863
3903
  },
3864
3904
  forwarderSupported: {
@@ -4171,6 +4211,7 @@ var EarnChain;
4171
4211
  v2: {
4172
4212
  type: 'split',
4173
4213
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4214
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4174
4215
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4175
4216
  confirmations: 1,
4176
4217
  fastConfirmations: 1
@@ -4216,6 +4257,7 @@ var EarnChain;
4216
4257
  v2: {
4217
4258
  type: 'split',
4218
4259
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4260
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4219
4261
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4220
4262
  confirmations: 1,
4221
4263
  fastConfirmations: 1
@@ -4261,6 +4303,7 @@ var EarnChain;
4261
4303
  v2: {
4262
4304
  type: 'split',
4263
4305
  tokenMessenger: '0x98706A006bc632Df31CAdFCBD43F38887ce2ca5c',
4306
+ tokenMessengerWithFees: '0x3Ac96675F9a3E6922713e041645D82f3561d3686',
4264
4307
  messageTransmitter: '0x5b61381Fc9e58E70EfC13a4A97516997019198ee',
4265
4308
  confirmations: 65,
4266
4309
  fastConfirmations: 1
@@ -4306,6 +4349,7 @@ var EarnChain;
4306
4349
  v2: {
4307
4350
  type: 'split',
4308
4351
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4352
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4309
4353
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4310
4354
  confirmations: 65,
4311
4355
  fastConfirmations: 1
@@ -4654,6 +4698,7 @@ var EarnChain;
4654
4698
  v2: {
4655
4699
  type: 'split',
4656
4700
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
4701
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
4657
4702
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
4658
4703
  confirmations: 1,
4659
4704
  fastConfirmations: 1
@@ -4701,6 +4746,7 @@ var EarnChain;
4701
4746
  v2: {
4702
4747
  type: 'split',
4703
4748
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
4749
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4704
4750
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4705
4751
  confirmations: 1,
4706
4752
  fastConfirmations: 1
@@ -4982,6 +5028,7 @@ var EarnChain;
4982
5028
  v2: {
4983
5029
  type: 'split',
4984
5030
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5031
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
4985
5032
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
4986
5033
  confirmations: 1,
4987
5034
  fastConfirmations: 1
@@ -5027,6 +5074,7 @@ var EarnChain;
5027
5074
  v2: {
5028
5075
  type: 'split',
5029
5076
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5077
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5030
5078
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5031
5079
  confirmations: 64,
5032
5080
  fastConfirmations: 1
@@ -5072,6 +5120,7 @@ var EarnChain;
5072
5120
  v2: {
5073
5121
  type: 'split',
5074
5122
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5123
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5075
5124
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5076
5125
  confirmations: 64,
5077
5126
  fastConfirmations: 1
@@ -5373,6 +5422,7 @@ var EarnChain;
5373
5422
  v2: {
5374
5423
  type: 'split',
5375
5424
  tokenMessenger: '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d',
5425
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_MAINNET,
5376
5426
  messageTransmitter: '0x81D40F21F12A8F0E3252Bccb954D722d4c464B64',
5377
5427
  confirmations: 1,
5378
5428
  fastConfirmations: 1
@@ -5419,6 +5469,7 @@ var EarnChain;
5419
5469
  v2: {
5420
5470
  type: 'split',
5421
5471
  tokenMessenger: '0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA',
5472
+ tokenMessengerWithFees: TOKEN_MESSENGER_WITH_FEES_EVM_TESTNET,
5422
5473
  messageTransmitter: '0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275',
5423
5474
  confirmations: 1,
5424
5475
  fastConfirmations: 1
@@ -5726,7 +5777,9 @@ var EarnChain;
5726
5777
  contracts: {
5727
5778
  v1: {
5728
5779
  wallet: GATEWAY_WALLET_EVM_MAINNET,
5729
- minter: GATEWAY_MINTER_EVM_MAINNET
5780
+ minter: GATEWAY_MINTER_EVM_MAINNET,
5781
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_MAINNET,
5782
+ genericExecutor: GENERIC_EXECUTOR_EVM_MAINNET
5730
5783
  }
5731
5784
  },
5732
5785
  forwarderSupported: {
@@ -5791,7 +5844,9 @@ var EarnChain;
5791
5844
  contracts: {
5792
5845
  v1: {
5793
5846
  wallet: GATEWAY_WALLET_EVM_TESTNET,
5794
- minter: GATEWAY_MINTER_EVM_TESTNET
5847
+ minter: GATEWAY_MINTER_EVM_TESTNET,
5848
+ depositForHandler: DEPOSIT_FOR_HANDLER_EVM_TESTNET,
5849
+ genericExecutor: GENERIC_EXECUTOR_EVM_TESTNET
5795
5850
  }
5796
5851
  },
5797
5852
  forwarderSupported: {
@@ -6877,6 +6932,67 @@ var Chains = /*#__PURE__*/Object.freeze({
6877
6932
  return chain.cctp?.contracts.v2 !== undefined;
6878
6933
  }
6879
6934
 
6935
+ /**
6936
+ * Chains the Fee Service accepts as a SOURCE for source-paid ("receive-exact")
6937
+ * CCTP v2 fees. An explicit allowlist is required because the
6938
+ * `TokenMessengerWithFees` wrapper address is now shared with the fast-deposit
6939
+ * forwarder path, so wrapper presence no longer implies source-fee support.
6940
+ * Keep in sync with backend coverage.
6941
+ */ new Set([
6942
+ // Mainnet
6943
+ Blockchain.Ethereum,
6944
+ Blockchain.Base,
6945
+ Blockchain.Arbitrum,
6946
+ Blockchain.Unichain,
6947
+ Blockchain.Optimism,
6948
+ Blockchain.Codex,
6949
+ Blockchain.Ink,
6950
+ Blockchain.Plume,
6951
+ Blockchain.Linea,
6952
+ Blockchain.World_Chain,
6953
+ // Testnet counterparts
6954
+ Blockchain.Ethereum_Sepolia,
6955
+ Blockchain.Base_Sepolia,
6956
+ Blockchain.Arbitrum_Sepolia,
6957
+ Blockchain.Unichain_Sepolia,
6958
+ Blockchain.Optimism_Sepolia,
6959
+ Blockchain.Codex_Testnet,
6960
+ Blockchain.Ink_Testnet,
6961
+ Blockchain.Plume_Testnet,
6962
+ Blockchain.Linea_Sepolia,
6963
+ Blockchain.World_Chain_Sepolia
6964
+ ]);
6965
+
6966
+ /**
6967
+ * Temporary allowlist of chains permitted to initiate Gateway fast deposits.
6968
+ * Only chains keyed here are eligible; all others are rejected. Using the
6969
+ * {@link Blockchain} enum keeps entries type-safe and catches typos at compile
6970
+ * time. Remove this allowlist once roll-out is complete.
6971
+ */ new Set([
6972
+ // Mainnet
6973
+ Blockchain.Ethereum,
6974
+ Blockchain.Base,
6975
+ Blockchain.Arbitrum,
6976
+ Blockchain.Unichain,
6977
+ Blockchain.Optimism,
6978
+ Blockchain.Codex,
6979
+ Blockchain.Ink,
6980
+ Blockchain.Plume,
6981
+ Blockchain.Linea,
6982
+ Blockchain.World_Chain,
6983
+ // Testnet counterparts
6984
+ Blockchain.Ethereum_Sepolia,
6985
+ Blockchain.Base_Sepolia,
6986
+ Blockchain.Arbitrum_Sepolia,
6987
+ Blockchain.Unichain_Sepolia,
6988
+ Blockchain.Optimism_Sepolia,
6989
+ Blockchain.Codex_Testnet,
6990
+ Blockchain.Ink_Testnet,
6991
+ Blockchain.Plume_Testnet,
6992
+ Blockchain.Linea_Sepolia,
6993
+ Blockchain.World_Chain_Sepolia
6994
+ ]);
6995
+
6880
6996
  /**
6881
6997
  * Zod schema for validating Gateway v1 contract addresses.
6882
6998
  *
@@ -6898,7 +7014,10 @@ var Chains = /*#__PURE__*/Object.freeze({
6898
7014
  }).min(1, 'Gateway minter address cannot be empty.'),
6899
7015
  depositForHandler: z.string({
6900
7016
  invalid_type_error: 'Gateway depositForHandler address must be a string.'
6901
- }).min(1, 'Gateway depositForHandler address cannot be empty.').optional()
7017
+ }).min(1, 'Gateway depositForHandler address cannot be empty.').optional(),
7018
+ genericExecutor: z.string({
7019
+ invalid_type_error: 'Gateway genericExecutor address must be a string.'
7020
+ }).min(1, 'Gateway genericExecutor address cannot be empty.').optional()
6902
7021
  }).strict() // Reject any additional properties not defined in the schema
6903
7022
  ;
6904
7023
  /**
@@ -9806,7 +9925,7 @@ const swapTokenEnumSchema = z.enum([
9806
9925
  * allowlisted {@link ClientLogPayload} fields (and the allowlisted
9807
9926
  * sub-fields of `errorDetails` / `clientContext`) are copied across.
9808
9927
  * A regressing upstream mapper — or a plain-JS caller that bypasses the
9809
- * type — therefore cannot exfiltrate stray properties (secrets, PII,
9928
+ * type — therefore cannot exfiltrate stray properties (secrets,
9810
9929
  * raw error stacks) through the analytics channel. Optional fields are
9811
9930
  * only included when present so the serialised shape matches the
9812
9931
  * server's strict schema.
@@ -9829,6 +9948,9 @@ const swapTokenEnumSchema = z.enum([
9829
9948
  if (payload.destinationChain !== undefined) safe['destinationChain'] = payload.destinationChain;
9830
9949
  if (payload.tokenIn !== undefined) safe['tokenIn'] = payload.tokenIn;
9831
9950
  if (payload.tokenOut !== undefined) safe['tokenOut'] = payload.tokenOut;
9951
+ if (payload.amountIn !== undefined) safe['amountIn'] = payload.amountIn;
9952
+ if (payload.durationMs !== undefined) safe['durationMs'] = payload.durationMs;
9953
+ if (payload.sourceAddress !== undefined) safe['sourceAddress'] = payload.sourceAddress;
9832
9954
  if (payload.txHash !== undefined) safe['txHash'] = payload.txHash;
9833
9955
  if (payload.correlationId !== undefined) safe['correlationId'] = payload.correlationId;
9834
9956
  if (payload.errorDetails !== undefined) {
@@ -10062,14 +10184,28 @@ const swapTokenEnumSchema = z.enum([
10062
10184
  }
10063
10185
 
10064
10186
  /**
10065
- * Soft signal for the case where building or emitting a telemetry payload
10066
- * threw — for example, a buggy `TelemetryContextResolver`, a regression in
10187
+ * Emit a stable console warning when building or emitting a telemetry payload
10188
+ * throws — for example, a buggy `TelemetryContextResolver`, a regression in
10067
10189
  * `extractErrorDetails`, or a synchronous failure inside `emitAnalyticsLog`
10068
- * before it could swallow the error itself. Logged with a stable prefix so
10069
- * consumers can grep for it. We deliberately do not re-throw: the caller's
10070
- * original operation error must always win.
10190
+ * before it could swallow the error itself. Uses a stable prefix so the
10191
+ * drop is discoverable via grep. Never re-throws: the caller's original
10192
+ * operation error must always win.
10071
10193
  *
10072
10194
  * @internal
10195
+ *
10196
+ * @param eventType - The telemetry event type that was being emitted.
10197
+ * @param cause - The error or value that caused the drop.
10198
+ *
10199
+ * @example
10200
+ * ```typescript
10201
+ * import { warnTelemetryDrop } from '@core/utils'
10202
+ *
10203
+ * try {
10204
+ * void emitAnalyticsLog(payload)
10205
+ * } catch (err) {
10206
+ * warnTelemetryDrop('my_event', err)
10207
+ * }
10208
+ * ```
10073
10209
  */ function warnTelemetryDrop(eventType, cause) {
10074
10210
  try {
10075
10211
  // Pass `cause` as the second console.warn argument rather than
@@ -10109,6 +10245,9 @@ const swapTokenEnumSchema = z.enum([
10109
10245
  ...context?.tokenOut != null && {
10110
10246
  tokenOut: context.tokenOut
10111
10247
  },
10248
+ ...context?.amountIn != null && {
10249
+ amountIn: context.amountIn
10250
+ },
10112
10251
  ...context?.txHash != null && {
10113
10252
  txHash: context.txHash
10114
10253
  },
@@ -10208,7 +10347,7 @@ const swapTokenEnumSchema = z.enum([
10208
10347
  }
10209
10348
 
10210
10349
  var name$2 = "@circle-fin/bridge-kit";
10211
- var version$2 = "1.14.0";
10350
+ var version$2 = "1.14.1";
10212
10351
  var pkg$2 = {
10213
10352
  name: name$2,
10214
10353
  version: version$2};
@@ -11173,6 +11312,241 @@ var TransferSpeed;
11173
11312
  message: 'Invalid metrics'
11174
11313
  });
11175
11314
 
11315
+ /**
11316
+ * Omit undefined values from an object.
11317
+ *
11318
+ * @param obj - The object to process.
11319
+ * @returns A new object with undefined values removed.
11320
+ *
11321
+ * @internal
11322
+ * @remarks
11323
+ * Used by both production and mock loggers to ensure consistent behavior.
11324
+ * This prevents undefined values from being serialized in log output,
11325
+ * which can cause issues with some log transports.
11326
+ */ function omitUndefined(obj) {
11327
+ const result = {};
11328
+ for (const [key, value] of Object.entries(obj)){
11329
+ if (value !== undefined) {
11330
+ result[key] = value;
11331
+ }
11332
+ }
11333
+ return result;
11334
+ }
11335
+
11336
+ /**
11337
+ * Default redaction paths for web3/blockchain SDKs.
11338
+ *
11339
+ * @remarks
11340
+ * These paths target common sensitive fields in blockchain applications.
11341
+ * All user fields are nested under `context`, so paths start with `context.`.
11342
+ * Wildcard `*` matches any key at that level.
11343
+ */ const DEFAULT_REDACT_PATHS = [
11344
+ // Generic Credentials
11345
+ 'context.password',
11346
+ 'context.passphrase',
11347
+ 'context.secret',
11348
+ 'context.token',
11349
+ 'context.*.password',
11350
+ 'context.*.passphrase',
11351
+ 'context.*.secret',
11352
+ 'context.*.token',
11353
+ // API Keys & Auth Tokens
11354
+ 'context.apiKey',
11355
+ 'context.apiSecret',
11356
+ 'context.accessToken',
11357
+ 'context.refreshToken',
11358
+ 'context.jwt',
11359
+ 'context.bearerToken',
11360
+ 'context.sessionId',
11361
+ 'context.authorization',
11362
+ 'context.cookie',
11363
+ 'context.*.apiKey',
11364
+ 'context.*.apiSecret',
11365
+ 'context.*.accessToken',
11366
+ 'context.*.refreshToken',
11367
+ 'context.*.jwt',
11368
+ 'context.*.bearerToken',
11369
+ 'context.*.sessionId',
11370
+ 'context.*.authorization',
11371
+ 'context.*.cookie',
11372
+ // Web3 / Crypto Keys
11373
+ 'context.privateKey',
11374
+ 'context.secretKey',
11375
+ 'context.signingKey',
11376
+ 'context.encryptionKey',
11377
+ 'context.*.privateKey',
11378
+ 'context.*.secretKey',
11379
+ 'context.*.signingKey',
11380
+ 'context.*.encryptionKey',
11381
+ // Web3 / Crypto Mnemonics and Seeds
11382
+ 'context.mnemonic',
11383
+ 'context.seed',
11384
+ 'context.seedPhrase',
11385
+ 'context.*.mnemonic',
11386
+ 'context.*.seed',
11387
+ 'context.*.seedPhrase',
11388
+ // OTP / Verification Codes
11389
+ 'context.otp',
11390
+ 'context.verificationCode',
11391
+ 'context.*.otp',
11392
+ 'context.*.verificationCode',
11393
+ // Payment Information
11394
+ 'context.cardNumber',
11395
+ 'context.cvv',
11396
+ 'context.accountNumber',
11397
+ 'context.*.cardNumber',
11398
+ 'context.*.cvv',
11399
+ 'context.*.accountNumber'
11400
+ ];
11401
+ /**
11402
+ * Wrap user fields under `context` to prevent collision with pino internals.
11403
+ *
11404
+ * @param fields - User-provided log fields.
11405
+ * @returns Object with fields nested under `context`, or undefined if empty.
11406
+ *
11407
+ * @remarks
11408
+ * This function handles edge cases by returning undefined for null, undefined,
11409
+ * or empty objects to avoid unnecessary wrapping in log output.
11410
+ * Undefined values are cleaned before wrapping.
11411
+ */ function wrapInContext(fields) {
11412
+ if (!fields) return undefined;
11413
+ // Clean undefined values for consistency and transport compatibility
11414
+ const cleaned = omitUndefined(fields);
11415
+ // Handle edge case: all values were undefined, resulting in empty object
11416
+ const keys = Object.keys(cleaned);
11417
+ if (keys.length === 0) return undefined;
11418
+ return {
11419
+ context: cleaned
11420
+ };
11421
+ }
11422
+ /**
11423
+ * Wrap a pino instance to conform to our Logger interface.
11424
+ *
11425
+ * @param pinoInstance - The pino logger instance to wrap.
11426
+ * @returns A Logger instance conforming to our stable interface.
11427
+ */ function wrapPino(pinoInstance) {
11428
+ return {
11429
+ debug (message, fields) {
11430
+ const wrapped = wrapInContext(fields);
11431
+ if (wrapped) {
11432
+ pinoInstance.debug(wrapped, message);
11433
+ } else {
11434
+ pinoInstance.debug(message);
11435
+ }
11436
+ },
11437
+ info (message, fields) {
11438
+ const wrapped = wrapInContext(fields);
11439
+ if (wrapped) {
11440
+ pinoInstance.info(wrapped, message);
11441
+ } else {
11442
+ pinoInstance.info(message);
11443
+ }
11444
+ },
11445
+ warn (message, fields) {
11446
+ const wrapped = wrapInContext(fields);
11447
+ if (wrapped) {
11448
+ pinoInstance.warn(wrapped, message);
11449
+ } else {
11450
+ pinoInstance.warn(message);
11451
+ }
11452
+ },
11453
+ error (message, fields) {
11454
+ const wrapped = wrapInContext(fields);
11455
+ if (wrapped) {
11456
+ pinoInstance.error(wrapped, message);
11457
+ } else {
11458
+ pinoInstance.error(message);
11459
+ }
11460
+ },
11461
+ child (tags) {
11462
+ // Child bindings stay flat (not wrapped) - they're part of logger's base context
11463
+ const cleaned = omitUndefined(tags);
11464
+ return wrapPino(pinoInstance.child(cleaned));
11465
+ }
11466
+ };
11467
+ }
11468
+ /**
11469
+ * Build pino redact configuration from our simplified options.
11470
+ *
11471
+ * @param redact - The redact configuration option.
11472
+ * @returns Pino-compatible redact configuration or undefined.
11473
+ */ function buildRedactConfig(redact) {
11474
+ // Explicitly disabled
11475
+ if (redact === false) {
11476
+ return undefined;
11477
+ }
11478
+ // Custom paths provided
11479
+ if (Array.isArray(redact)) {
11480
+ return redact.length > 0 ? {
11481
+ paths: redact,
11482
+ censor: '[REDACTED]'
11483
+ } : undefined;
11484
+ }
11485
+ // Default: use web3 sensible defaults
11486
+ return {
11487
+ paths: [
11488
+ ...DEFAULT_REDACT_PATHS
11489
+ ],
11490
+ censor: '[REDACTED]'
11491
+ };
11492
+ }
11493
+ /**
11494
+ * Create a logger backed by pino.
11495
+ *
11496
+ * @param options - Logger options (optional).
11497
+ * @param stream - Destination stream (optional).
11498
+ * @returns A Logger instance.
11499
+ * @throws Error if invalid pino options are provided.
11500
+ *
11501
+ * @remarks
11502
+ * This is a thin wrapper around pino that exposes our stable Logger interface.
11503
+ * Pino handles all transport concerns: JSON, pretty printing, file, remote, browser, etc.
11504
+ *
11505
+ * **Security**: By default, sensitive web3 fields (privateKey, mnemonic, apiKey, etc.)
11506
+ * are automatically redacted from log output. Use `redact: false` to disable.
11507
+ *
11508
+ * @example
11509
+ * ```typescript
11510
+ * import { createLogger } from '@core/runtime'
11511
+ *
11512
+ * // Default: web3 sensitive fields are redacted
11513
+ * const logger = createLogger({ level: 'info' })
11514
+ * logger.info('Signing', { privateKey: '0x123...' })
11515
+ * // Output: { context: { privateKey: '[REDACTED]' }, msg: 'Signing' }
11516
+ *
11517
+ * // Disable redaction (use with caution)
11518
+ * const unsafeLogger = createLogger({ level: 'debug', redact: false })
11519
+ *
11520
+ * // Custom redaction paths
11521
+ * const customLogger = createLogger({
11522
+ * level: 'info',
11523
+ * redact: ['context.mySecret', 'context.*.credentials']
11524
+ * })
11525
+ *
11526
+ * // Pretty output for development
11527
+ * const devLogger = createLogger({
11528
+ * level: 'debug',
11529
+ * transport: { target: 'pino-pretty' }
11530
+ * })
11531
+ *
11532
+ * // Browser logger
11533
+ * const browserLogger = createLogger({
11534
+ * browser: { asObject: true }
11535
+ * })
11536
+ * ```
11537
+ */ function createLogger(options, stream) {
11538
+ const { redact, ...pinoOptions } = options ?? {};
11539
+ // Build redaction config
11540
+ const redactConfig = buildRedactConfig(redact);
11541
+ // Build final pino options, only include redact if defined
11542
+ const finalOptions = redactConfig ? {
11543
+ ...pinoOptions,
11544
+ redact: redactConfig
11545
+ } : pinoOptions;
11546
+ const pinoInstance = pino(finalOptions);
11547
+ return wrapPino(pinoInstance);
11548
+ }
11549
+
11176
11550
  // ============================================================================
11177
11551
  // Validation Schema
11178
11552
  // ============================================================================
@@ -11280,6 +11654,9 @@ var TransferSpeed;
11280
11654
  [TransferSpeed.SLOW]: 2000
11281
11655
  });
11282
11656
 
11657
+ createLogger({
11658
+ name: 'provider-cctp-v2'
11659
+ });
11283
11660
  /**
11284
11661
  * All chains that are supported by the CCTP v2 provider.
11285
11662
  *
@@ -11289,7 +11666,11 @@ var TransferSpeed;
11289
11666
  * @internal
11290
11667
  */ Object.values(Chains).filter((chain)=>isCCTPV2Supported(chain));
11291
11668
 
11292
- /** Decimal string in token minor units, constrained to be strictly positive. */ const positiveAmountSchema = z.string().regex(/^\d+$/, 'must be a non-negative integer string')// Re-check the digit shape here: zod still runs this refinement when the
11669
+ /**
11670
+ * Decimal string in token minor units, constrained to be strictly positive.
11671
+ *
11672
+ * @internal
11673
+ */ const positiveAmountSchema = z.string().regex(/^\d+$/, 'must be a non-negative integer string')// Re-check the digit shape here: zod still runs this refinement when the
11293
11674
  // regex check above fails ("dirty"), so guard BigInt() against throwing on a
11294
11675
  // non-numeric value before comparing.
11295
11676
  .refine((value)=>/^\d+$/.test(value) && BigInt(value) > 0n, 'must be greater than zero');
@@ -11324,11 +11705,19 @@ const forwardRequestSchema = z.object({
11324
11705
  const preFinalityRequestSchema = z.object({
11325
11706
  type: z.literal('PRE_FINALITY')
11326
11707
  }).strict();
11327
- /** A single quote request item (`FORWARD` or `PRE_FINALITY`). */ const feeQuoteRequestSchema = z.discriminatedUnion('type', [
11708
+ /**
11709
+ * A single quote request item (`FORWARD` or `PRE_FINALITY`).
11710
+ *
11711
+ * @internal
11712
+ */ const feeQuoteRequestSchema = z.discriminatedUnion('type', [
11328
11713
  forwardRequestSchema,
11329
11714
  preFinalityRequestSchema
11330
11715
  ]);
11331
- /** A non-empty list of quote request items with unique types. */ const feeQuoteRequestsSchema = z.array(feeQuoteRequestSchema).min(1, 'at least one request item is required').refine((items)=>new Set(items.map((item)=>item.type)).size === items.length, 'request item types must be unique');
11716
+ /**
11717
+ * A non-empty list of quote request items with unique types.
11718
+ *
11719
+ * @internal
11720
+ */ const feeQuoteRequestsSchema = z.array(feeQuoteRequestSchema).min(1, 'at least one request item is required').refine((items)=>new Set(items.map((item)=>item.type)).size === items.length, 'request item types must be unique');
11332
11721
  /**
11333
11722
  * A structured `Partial<ApiPollingConfig>` polling override.
11334
11723
  *
@@ -11356,6 +11745,8 @@ const preFinalityRequestSchema = z.object({
11356
11745
  * it `undefined`, which is falsy and silently selects the production base URL.
11357
11746
  * (`buildFeeQuoteUrl` independently re-validates the domains for standalone
11358
11747
  * callers.)
11748
+ *
11749
+ * @internal
11359
11750
  */ z.object({
11360
11751
  sourceDomain: z.number().int().nonnegative(),
11361
11752
  destinationDomain: z.number().int().nonnegative(),
@@ -11391,7 +11782,11 @@ const metadataSchema = z.object({
11391
11782
  blockEstimatedAt: z.number().int().nonnegative().optional()
11392
11783
  }).passthrough()
11393
11784
  ]);
11394
- /** Schema for a signed fee quote returned by the Quote API. */ z.object({
11785
+ /**
11786
+ * Schema for a signed fee quote returned by the Quote API.
11787
+ *
11788
+ * @internal
11789
+ */ z.object({
11395
11790
  // The runtime YAML spec maps signedQuote to a looser `hex` (which allows
11396
11791
  // an empty `0x`); we keep the stricter non-empty form. Do not relax
11397
11792
  // without a reason.
@@ -11405,7 +11800,11 @@ const metadataSchema = z.object({
11405
11800
  items: z.array(feeQuoteItemSchema),
11406
11801
  metadata: metadataSchema.optional()
11407
11802
  }).passthrough();
11408
- /** Validate input to {@link validateQuote}. */ z.object({
11803
+ /**
11804
+ * Validates input to {@link validateQuote}.
11805
+ *
11806
+ * @internal
11807
+ */ z.object({
11409
11808
  sourceDomain: z.number().int().nonnegative(),
11410
11809
  abiSignature: z.string().min(1),
11411
11810
  args: z.array(z.union([
@@ -11440,11 +11839,13 @@ const validateQuoteItemSchema = z.object({
11440
11839
  computedArgsHash: bytes32Schema.optional()
11441
11840
  }).passthrough();
11442
11841
  /**
11443
- * Schema for a response from the Quote API validation endpoint.
11842
+ * Schema for a validate-quote result returned by the Iris `/validate/usdc/:sourceDomain` endpoint.
11444
11843
  *
11445
11844
  * The endpoint takes the source domain as a URL path parameter and does not
11446
11845
  * return it in the response body, so `sourceDomain` is intentionally not part
11447
11846
  * of this schema.
11847
+ *
11848
+ * @internal
11448
11849
  */ z.object({
11449
11850
  signedQuote: nonEmptyHexSchema,
11450
11851
  expiry: quoteExpiryStatusSchema,
@@ -11464,7 +11865,7 @@ const validateQuoteItemSchema = z.object({
11464
11865
  registerKit(`${pkg$2.name}/${pkg$2.version}`);
11465
11866
 
11466
11867
  var name$1 = "@circle-fin/swap-kit";
11467
- var version$1 = "1.6.0";
11868
+ var version$1 = "1.6.1";
11468
11869
  var pkg$1 = {
11469
11870
  name: name$1,
11470
11871
  version: version$1};
@@ -21836,7 +22237,7 @@ registerKit(`${pkg$1.name}/${pkg$1.version}`);
21836
22237
  };
21837
22238
 
21838
22239
  var name = "@circle-fin/earn-kit";
21839
- var version = "1.6.0";
22240
+ var version = "1.6.1";
21840
22241
  var pkg = {
21841
22242
  name: name,
21842
22243
  version: version};