@chipi-stack/backend 14.8.0 → 14.10.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.mjs CHANGED
@@ -387,6 +387,9 @@ function ed25519PubkeyFelts(publicKey) {
387
387
  const { low, high } = bytesToLeU256(publicKey);
388
388
  return [low, high];
389
389
  }
390
+ function ed25519OwnerPubkeyParam(publicKey) {
391
+ return ed25519PubkeyFelts(publicKey).map((f) => "0x" + f.toString(16)).join(",");
392
+ }
390
393
  async function buildEd25519Envelope(params) {
391
394
  const ownerIndex = params.ownerIndex ?? 0n;
392
395
  if (ownerIndex < 0n || ownerIndex >= 0x100000000n) {
@@ -497,6 +500,14 @@ var init_encryption2 = __esm({
497
500
  init_encryption();
498
501
  }
499
502
  });
503
+
504
+ // src/shhh/signers/stark.ts
505
+ var stark_exports = {};
506
+ __export(stark_exports, {
507
+ buildStarkEnvelope: () => buildStarkEnvelope,
508
+ starkOwnerId: () => starkOwnerId,
509
+ starkPubkeyFelts: () => starkPubkeyFelts
510
+ });
500
511
  function buildStarkEnvelope(params) {
501
512
  const pkHex = "0x" + (typeof params.privateKey === "bigint" ? params.privateKey : BigInt(params.privateKey)).toString(16).padStart(64, "0");
502
513
  const sig = ec.starkCurve.sign("0x" + params.messageHash.toString(16), pkHex);
@@ -947,7 +958,15 @@ var executePaymasterTransaction = async ({
947
958
  usePasskey ? "encryptKey is required when using passkey. The passkey authentication should have provided the encryptKey." : "encryptKey is required for transaction execution"
948
959
  );
949
960
  }
950
- const walletType = wallet.walletType ?? "READY";
961
+ let walletType = wallet.walletType ?? "READY";
962
+ if (!wallet.walletType) {
963
+ try {
964
+ const resolveProvider = new RpcProvider({ nodeUrl: WALLET_RPC_ENDPOINTS.CHIPI });
965
+ const onChainClassHash = await resolveProvider.getClassHashAt(wallet.publicKey, "latest");
966
+ walletType = getWalletTypeFromClassHash(onChainClassHash) ?? "READY";
967
+ } catch {
968
+ }
969
+ }
951
970
  if (walletType === "SHHH") {
952
971
  const { executeShhhSponsoredRaw: executeShhhSponsoredRaw2 } = await Promise.resolve().then(() => (init_execute_paymaster_raw(), execute_paymaster_raw_exports));
953
972
  const shhhSignerKind = (wallet.signerKind ?? "STARK") || "STARK";
@@ -2523,7 +2542,7 @@ var ChipiSessions = class {
2523
2542
  * Set a spending policy for a session key + token pair.
2524
2543
  *
2525
2544
  * This executes a sponsored transaction (using owner signature) to call
2526
- * `set_spending_policy` on the CHIPI wallet contract.
2545
+ * `set_spending_policy` on the wallet contract (CHIPI v29 or SHHH V8.4).
2527
2546
  *
2528
2547
  * The contract enforces these limits automatically during `__execute__()` on
2529
2548
  * ERC-20 operations (transfer, approve, increase_allowance) made by the session.
@@ -2551,9 +2570,9 @@ var ChipiSessions = class {
2551
2570
  async setSpendingPolicy(params, bearerToken) {
2552
2571
  const { encryptKey, wallet, spendingPolicyConfig } = params;
2553
2572
  const { sessionPublicKey, token, maxPerCall, maxPerWindow, windowSeconds } = spendingPolicyConfig;
2554
- if (wallet.walletType && wallet.walletType !== "CHIPI") {
2573
+ if (wallet.walletType && wallet.walletType !== "CHIPI" && wallet.walletType !== "SHHH") {
2555
2574
  throw new ChipiSessionError(
2556
- `Spending policies only support CHIPI wallets. Got: ${wallet.walletType}`,
2575
+ `Spending policies require CHIPI or SHHH wallet type. Got: ${wallet.walletType}`,
2557
2576
  SESSION_ERRORS.INVALID_WALLET_TYPE_FOR_SESSION
2558
2577
  );
2559
2578
  }
@@ -2612,7 +2631,7 @@ var ChipiSessions = class {
2612
2631
  const txHash = await executePaymasterTransaction({
2613
2632
  params: {
2614
2633
  encryptKey,
2615
- wallet: { ...wallet, walletType: "CHIPI" },
2634
+ wallet,
2616
2635
  calls: [
2617
2636
  {
2618
2637
  contractAddress: wallet.publicKey,
@@ -2748,7 +2767,7 @@ var ChipiSessions = class {
2748
2767
  * Remove a spending policy for a session key + token pair.
2749
2768
  *
2750
2769
  * This executes a sponsored transaction (using owner signature) to call
2751
- * `remove_spending_policy` on the CHIPI wallet contract.
2770
+ * `remove_spending_policy` on the wallet contract (CHIPI v29 or SHHH V8.4).
2752
2771
  *
2753
2772
  * After removal, the session key has no spending limits for this token.
2754
2773
  *
@@ -2768,9 +2787,9 @@ var ChipiSessions = class {
2768
2787
  */
2769
2788
  async removeSpendingPolicy(params, bearerToken) {
2770
2789
  const { encryptKey, wallet, sessionPublicKey, token } = params;
2771
- if (wallet.walletType && wallet.walletType !== "CHIPI") {
2790
+ if (wallet.walletType && wallet.walletType !== "CHIPI" && wallet.walletType !== "SHHH") {
2772
2791
  throw new ChipiSessionError(
2773
- `Spending policies only support CHIPI wallets. Got: ${wallet.walletType}`,
2792
+ `Spending policies require CHIPI or SHHH wallet type. Got: ${wallet.walletType}`,
2774
2793
  SESSION_ERRORS.INVALID_WALLET_TYPE_FOR_SESSION
2775
2794
  );
2776
2795
  }
@@ -2790,7 +2809,7 @@ var ChipiSessions = class {
2790
2809
  const txHash = await executePaymasterTransaction({
2791
2810
  params: {
2792
2811
  encryptKey,
2793
- wallet: { ...wallet, walletType: "CHIPI" },
2812
+ wallet,
2794
2813
  calls: [
2795
2814
  {
2796
2815
  contractAddress: wallet.publicKey,
@@ -3160,6 +3179,43 @@ var signTypedData = async ({
3160
3179
  throw error;
3161
3180
  }
3162
3181
  };
3182
+ function toFeltHex(x) {
3183
+ return "0x" + x.toString(16).padStart(64, "0");
3184
+ }
3185
+ var signTypedDataArray = async ({
3186
+ params
3187
+ }) => {
3188
+ const { encryptKey, wallet, typedData: typedData2 } = params;
3189
+ if (!encryptKey) throw new Error("encryptKey is required for signing typed data");
3190
+ if (!wallet || !wallet.encryptedPrivateKey || !wallet.publicKey) {
3191
+ throw new Error("wallet with publicKey and encryptedPrivateKey is required");
3192
+ }
3193
+ if (!typedData2) throw new Error("typedData is required for signing");
3194
+ const walletType = wallet.walletType ?? "READY";
3195
+ if (!Object.prototype.hasOwnProperty.call(WALLET_RPC_ENDPOINTS, walletType)) {
3196
+ throw new Error(`Unsupported wallet type: "${String(walletType)}"`);
3197
+ }
3198
+ let privateKeyDecrypted;
3199
+ try {
3200
+ privateKeyDecrypted = decryptPrivateKey(wallet.encryptedPrivateKey, encryptKey);
3201
+ } catch {
3202
+ throw new Error("Failed to decrypt private key. Verify the encryptKey is correct.");
3203
+ }
3204
+ const messageHash = BigInt(typedData.getMessageHash(typedData2, wallet.publicKey));
3205
+ if (walletType === "SHHH") {
3206
+ const { buildStarkEnvelope: buildStarkEnvelope2 } = await Promise.resolve().then(() => (init_stark(), stark_exports));
3207
+ const envelope = buildStarkEnvelope2({
3208
+ privateKey: privateKeyDecrypted,
3209
+ messageHash,
3210
+ ownerIndex: 0n
3211
+ });
3212
+ return envelope.map(toFeltHex);
3213
+ }
3214
+ const provider = new RpcProvider({ nodeUrl: WALLET_RPC_ENDPOINTS[walletType] });
3215
+ const account = new Account({ provider, address: wallet.publicKey, signer: privateKeyDecrypted });
3216
+ const { r, s } = normalizeSignature(await account.signMessage(typedData2));
3217
+ return [r, s];
3218
+ };
3163
3219
 
3164
3220
  // src/chipi-sdk.ts
3165
3221
  var ChipiSDK = class {
@@ -3184,6 +3240,7 @@ var ChipiSDK = class {
3184
3240
  this.purchaseSku = this.purchaseSku.bind(this);
3185
3241
  this.getUsdAmount = this.getUsdAmount.bind(this);
3186
3242
  this.signTypedData = this.signTypedData.bind(this);
3243
+ this.signTypedDataArray = this.signTypedDataArray.bind(this);
3187
3244
  this.createPaymasterAdapter = this.createPaymasterAdapter.bind(this);
3188
3245
  this.createX402Facilitator = this.createX402Facilitator.bind(this);
3189
3246
  }
@@ -3312,6 +3369,14 @@ var ChipiSDK = class {
3312
3369
  async signTypedData({ params }) {
3313
3370
  return signTypedData({ params });
3314
3371
  }
3372
+ /**
3373
+ * Sign SNIP-12 typed data and return the full signature span (felt strings) —
3374
+ * the shape a dApp's `wallet_signTypedData` expects. Wallet-type aware:
3375
+ * SHHH returns the V2_SNIP12 owner envelope; standard accounts return [r, s].
3376
+ */
3377
+ async signTypedDataArray({ params }) {
3378
+ return signTypedDataArray({ params });
3379
+ }
3315
3380
  /**
3316
3381
  * Transfer tokens
3317
3382
  */
@@ -3834,6 +3899,12 @@ function eip191PubkeyFelts(pubkey) {
3834
3899
  function eip191OwnerId(pubkey) {
3835
3900
  return ownerCommitment(EIP191_KIND_TAG_FELT, eip191PubkeyFelts(pubkey));
3836
3901
  }
3902
+ function eip191OwnerPubkeyParam(pubkey) {
3903
+ assertBytes("secp256k1 x coordinate", pubkey.x, 32);
3904
+ assertBytes("secp256k1 y coordinate", pubkey.y, 32);
3905
+ const toHex = (b) => "0x" + Array.from(b, (v) => v.toString(16).padStart(2, "0")).join("");
3906
+ return `${toHex(pubkey.x)},${toHex(pubkey.y)}`;
3907
+ }
3837
3908
  function parseEip191Signature(signatureHex) {
3838
3909
  const hex = signatureHex.startsWith("0x") ? signatureHex.slice(2) : signatureHex;
3839
3910
  if (hex.length !== 130) {
@@ -4056,6 +4127,12 @@ function webauthnPubkeyFelts(pub) {
4056
4127
  function webauthnOwnerId(pub) {
4057
4128
  return ownerCommitment(WEBAUTHN_KIND_TAG_FELT, webauthnPubkeyFelts(pub));
4058
4129
  }
4130
+ function webauthnOwnerPubkeyParam(pub) {
4131
+ assertBytes2("P-256 x coordinate", pub.x, 32);
4132
+ assertBytes2("P-256 y coordinate", pub.y, 32);
4133
+ const toHex = (b) => "0x" + Array.from(b, (v) => v.toString(16).padStart(2, "0")).join("");
4134
+ return `${toHex(pub.x)},${toHex(pub.y)}`;
4135
+ }
4059
4136
  function buildWebAuthnEnvelopeFromAssertion(params) {
4060
4137
  const ownerIndex = params.ownerIndex ?? 0n;
4061
4138
  if (ownerIndex < 0n || ownerIndex >= 0x100000000n) {
@@ -4611,6 +4688,82 @@ function secondsUntilExecutable(validAfterSecs, nowSecs) {
4611
4688
  init_threshold();
4612
4689
  init_execute_paymaster_raw();
4613
4690
 
4614
- export { ANY_CALLER_FELT, APPLE_ISSUER, BOOTSTRAP_DOMAIN_SEPARATOR, ChipiBrowserSDK, ChipiClient, ChipiPaymasterAdapter, ChipiSDK, ChipiServerSDK, ChipiSessions, ChipiSkuPurchases, ChipiSkus, ChipiTransactions, ChipiTreasury, ChipiWallets, DEFAULT_OP_EXPIRY_SECONDS, ISIGNER_CANONICAL_LABEL, ISIGNER_ID, ISRC9_V2_ID, MAX_OE_VALIDITY_WINDOW_SECONDS, MIN_THRESHOLD_OWNERS, OE_DOMAIN_NAME, OE_DOMAIN_REVISION, OE_DOMAIN_VERSION, OP_ADD_OWNER, OP_REMOVE_OWNER, OP_ROTATE_OWNER, OP_SET_THRESHOLD, ROLE_GUARDIAN, ROLE_OWNER, SIG_VERSION_V1_HEX_ASCII, SIG_VERSION_V2_SNIP12, SIG_VERSION_V2_THRESHOLD, STARKNET_MESSAGE_PREFIX, TIMELOCK_SECONDS, VIEW_SELECTORS, X402Facilitator, X402ShhhClient, assertValidV2Snip12Envelope, buildBootstrapSignedCall, buildCancelPendingOpCall, buildCancelRecoveryCall, buildEd25519Envelope, buildEd25519EnvelopeFromSignature, buildEip191EnvelopeFromPrivateKey, buildEip191EnvelopeFromSignature, buildExecuteAddOwnerCall, buildExecuteRemoveOwnerCall, buildExecuteRotateOwnerCall, buildExecuteSetThresholdCall, buildFinalizeRecoveryCall, buildInitiateRecoveryCall, buildJwtAppleSubEnvelopeFromTestKey, buildJwtAppleSubEnvelopeFromTokenResponse, buildMigrationCalls, buildOutsideExecution, buildProposeAddOwnerCall, buildProposeRemoveOwnerCall, buildProposeRotateOwnerCall, buildProposeSetThresholdCall, buildStarkEnvelope, buildThresholdEnvelope, buildWebAuthnEnvelopeFromAssertion, buildWebAuthnEnvelopeFromPrivateKey, byteArrayToFelts, computeAddressSalt, computeBootstrapMessage, computeISignerId, computeOeHash, computeShhhAddress, computeSnip12Hash, decryptPrivateKey, ed25519OwnerId, ed25519PubkeyFelts, ed25519SignedBytes, eip191OwnerId, eip191PubkeyFelts, encryptPrivateKey, estimateThresholdGasOverhead, executeShhhSponsoredRaw, hashCall, hashCalls, hashOutsideExecutionStruct, hashStarknetDomain, isReadyToExecute, jwtAppleSubHash, jwtAppleSubOwnerId, jwtAppleSubPubkeyFelts, labelToFelt, locateSubClaim, messageHashToNonceB64url, migrateChipiWalletToShhh, ownerCommitment, parseAppleIdToken, parseDerEcdsaSignature, parseEip191Signature, parseThresholdEnvelope, resolveShhhChainId, secondsUntilExecutable, serializeExecuteFromOutsideV2Calldata, signBootstrapMessage, signTypedData, snip12HashToHexAsciiBytes, starkOwnerId, starkPubkeyFelts, webauthnOwnerId, webauthnPubkeyFelts, wrapV2Snip12Envelope, wrapV2ThresholdEnvelope, x402Middleware };
4691
+ // src/shhh/account.ts
4692
+ init_oe();
4693
+ init_stark();
4694
+ init_execute_paymaster_raw();
4695
+ function generateNonce2() {
4696
+ return BigInt(Date.now()) << 24n | BigInt(Math.floor(Math.random() * 16777216));
4697
+ }
4698
+ var ShhhAccount = class {
4699
+ constructor(provider, address, privateKey, options = {}) {
4700
+ this.provider = provider;
4701
+ this.address = address;
4702
+ this.privateKey = privateKey;
4703
+ this.ownerIndex = options.ownerIndex ?? 0n;
4704
+ this.chainId = options.chainId ?? resolveShhhChainId({});
4705
+ this.submitFn = options.submit;
4706
+ }
4707
+ /**
4708
+ * Build + sign an OutsideExecution for `calls` and return the
4709
+ * serialized `execute_from_outside_v2` calldata (plus the underlying
4710
+ * pieces). Use this when you want to broadcast the calldata yourself.
4711
+ */
4712
+ async signExecution(calls, options = {}) {
4713
+ if (options.validForSeconds !== void 0) {
4714
+ const maxValid = MAX_OE_VALIDITY_WINDOW_SECONDS - OE_EXECUTE_AFTER_CLOCK_SKEW_BUFFER;
4715
+ if (!Number.isFinite(options.validForSeconds) || options.validForSeconds <= 0) {
4716
+ throw new Error(
4717
+ "ShhhAccount: validForSeconds must be a positive finite number of seconds."
4718
+ );
4719
+ }
4720
+ if (options.validForSeconds > maxValid) {
4721
+ throw new Error(
4722
+ `ShhhAccount: validForSeconds (${options.validForSeconds}) exceeds the max ${maxValid}s (the account caps the OE window at ${MAX_OE_VALIDITY_WINDOW_SECONDS}s and ${OE_EXECUTE_AFTER_CLOCK_SKEW_BUFFER}s is reserved for clock skew).`
4723
+ );
4724
+ }
4725
+ }
4726
+ const outsideExecution = buildOutsideExecution({
4727
+ nonce: options.nonce ?? generateNonce2(),
4728
+ calls,
4729
+ ...options.validForSeconds !== void 0 ? { executeBefore: BigInt(Math.floor(Date.now() / 1e3) + options.validForSeconds) } : {}
4730
+ });
4731
+ const messageHash = computeOeHash(outsideExecution, this.address, this.chainId);
4732
+ const signature = buildStarkEnvelope({
4733
+ privateKey: this.privateKey,
4734
+ messageHash,
4735
+ ownerIndex: this.ownerIndex
4736
+ });
4737
+ const calldata = serializeExecuteFromOutsideV2Calldata({ outsideExecution, signature });
4738
+ return { outsideExecution, signature, messageHash, calldata };
4739
+ }
4740
+ /**
4741
+ * Sign `calls` and broadcast them via the configured `submit` strategy.
4742
+ * Mirrors starknet.js `Account.execute` ergonomically. Returns the
4743
+ * transaction hash without waiting for inclusion — use
4744
+ * `provider.waitForTransaction(transactionHash)` if you need to block.
4745
+ */
4746
+ async execute(calls, options = {}) {
4747
+ if (!this.submitFn) {
4748
+ throw new Error(
4749
+ "ShhhAccount.execute: no submit strategy configured. Pass `submit` in the ShhhAccount constructor options (e.g. submitViaAccount(fundedAccount) for self-sovereign, or a paymaster relay for gasless), or call signExecution() and broadcast the calldata yourself."
4750
+ );
4751
+ }
4752
+ const { calldata } = await this.signExecution(calls, options);
4753
+ return this.submitFn({ accountAddress: this.address, calldata });
4754
+ }
4755
+ };
4756
+ function submitViaAccount(funded) {
4757
+ return async ({ accountAddress, calldata }) => {
4758
+ const { transaction_hash } = await funded.execute({
4759
+ contractAddress: accountAddress,
4760
+ entrypoint: "execute_from_outside_v2",
4761
+ calldata
4762
+ });
4763
+ return { transactionHash: transaction_hash };
4764
+ };
4765
+ }
4766
+
4767
+ export { ANY_CALLER_FELT, APPLE_ISSUER, BOOTSTRAP_DOMAIN_SEPARATOR, ChipiBrowserSDK, ChipiClient, ChipiPaymasterAdapter, ChipiSDK, ChipiServerSDK, ChipiSessions, ChipiSkuPurchases, ChipiSkus, ChipiTransactions, ChipiTreasury, ChipiWallets, DEFAULT_OP_EXPIRY_SECONDS, ISIGNER_CANONICAL_LABEL, ISIGNER_ID, ISRC9_V2_ID, MAX_OE_VALIDITY_WINDOW_SECONDS, MIN_THRESHOLD_OWNERS, OE_DOMAIN_NAME, OE_DOMAIN_REVISION, OE_DOMAIN_VERSION, OP_ADD_OWNER, OP_REMOVE_OWNER, OP_ROTATE_OWNER, OP_SET_THRESHOLD, ROLE_GUARDIAN, ROLE_OWNER, SIG_VERSION_V1_HEX_ASCII, SIG_VERSION_V2_SNIP12, SIG_VERSION_V2_THRESHOLD, STARKNET_MESSAGE_PREFIX, ShhhAccount, TIMELOCK_SECONDS, VIEW_SELECTORS, X402Facilitator, X402ShhhClient, assertValidV2Snip12Envelope, buildBootstrapSignedCall, buildCancelPendingOpCall, buildCancelRecoveryCall, buildEd25519Envelope, buildEd25519EnvelopeFromSignature, buildEip191EnvelopeFromPrivateKey, buildEip191EnvelopeFromSignature, buildExecuteAddOwnerCall, buildExecuteRemoveOwnerCall, buildExecuteRotateOwnerCall, buildExecuteSetThresholdCall, buildFinalizeRecoveryCall, buildInitiateRecoveryCall, buildJwtAppleSubEnvelopeFromTestKey, buildJwtAppleSubEnvelopeFromTokenResponse, buildMigrationCalls, buildOutsideExecution, buildProposeAddOwnerCall, buildProposeRemoveOwnerCall, buildProposeRotateOwnerCall, buildProposeSetThresholdCall, buildStarkEnvelope, buildThresholdEnvelope, buildWebAuthnEnvelopeFromAssertion, buildWebAuthnEnvelopeFromPrivateKey, byteArrayToFelts, computeAddressSalt, computeBootstrapMessage, computeISignerId, computeOeHash, computeShhhAddress, computeSnip12Hash, decryptPrivateKey, ed25519OwnerId, ed25519OwnerPubkeyParam, ed25519PubkeyFelts, ed25519SignedBytes, eip191OwnerId, eip191OwnerPubkeyParam, eip191PubkeyFelts, encryptPrivateKey, estimateThresholdGasOverhead, executeShhhSponsoredRaw, hashCall, hashCalls, hashOutsideExecutionStruct, hashStarknetDomain, isReadyToExecute, jwtAppleSubHash, jwtAppleSubOwnerId, jwtAppleSubPubkeyFelts, labelToFelt, locateSubClaim, messageHashToNonceB64url, migrateChipiWalletToShhh, ownerCommitment, parseAppleIdToken, parseDerEcdsaSignature, parseEip191Signature, parseThresholdEnvelope, resolveShhhChainId, secondsUntilExecutable, serializeExecuteFromOutsideV2Calldata, signBootstrapMessage, signTypedData, signTypedDataArray, snip12HashToHexAsciiBytes, starkOwnerId, starkPubkeyFelts, submitViaAccount, webauthnOwnerId, webauthnOwnerPubkeyParam, webauthnPubkeyFelts, wrapV2Snip12Envelope, wrapV2ThresholdEnvelope, x402Middleware };
4615
4768
  //# sourceMappingURL=index.mjs.map
4616
4769
  //# sourceMappingURL=index.mjs.map