@chipi-stack/backend 14.16.0 → 14.17.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
@@ -173,9 +173,9 @@ function assertValidV2Snip12Envelope(envelope) {
173
173
  }
174
174
  return envelope[1];
175
175
  }
176
- function _tryDecodeShortString(felt) {
176
+ function _tryDecodeShortString(felt2) {
177
177
  try {
178
- return starknet.shortString.decodeShortString("0x" + felt.toString(16));
178
+ return starknet.shortString.decodeShortString("0x" + felt2.toString(16));
179
179
  } catch {
180
180
  return null;
181
181
  }
@@ -199,14 +199,20 @@ function buildThresholdEnvelope(args) {
199
199
  );
200
200
  }
201
201
  seenOwners.add(key);
202
- out.push(BigInt(env.length));
203
- for (const felt of env) {
204
- if (felt < 0n) {
202
+ if (env.length < 3) {
203
+ throw new Error(
204
+ `THRESH: inner envelope ${i} must have at least [tag, owner_id, kind_tag]; got ${env.length} felts`
205
+ );
206
+ }
207
+ const frame = env.slice(1);
208
+ out.push(BigInt(frame.length));
209
+ for (const felt2 of frame) {
210
+ if (felt2 < 0n) {
205
211
  throw new RangeError(
206
212
  `THRESH: envelope ${i} contains negative felt (cannot serialize as felt252)`
207
213
  );
208
214
  }
209
- out.push(felt);
215
+ out.push(felt2);
210
216
  }
211
217
  }
212
218
  return out;
@@ -239,15 +245,26 @@ function parseThresholdEnvelope(envelope) {
239
245
  `THRESH: inner ${i} would overflow envelope (env_len ${envLen}, cursor ${cursor}, total ${envelope.length})`
240
246
  );
241
247
  }
242
- const inner = envelope.slice(cursor, cursor + envLen);
243
- for (const felt of inner) {
244
- if (felt < 0n) {
248
+ const frame = envelope.slice(cursor, cursor + envLen);
249
+ for (const felt2 of frame) {
250
+ if (felt2 < 0n) {
245
251
  throw new RangeError(
246
252
  `THRESH: inner ${i} contains negative felt (cannot serialize as felt252)`
247
253
  );
248
254
  }
249
255
  }
250
- const ownerId = assertValidV2Snip12Envelope(inner);
256
+ const ownerId = frame[0];
257
+ if (ownerId >= 0x100000000n) {
258
+ if (ownerId === V2_THRESHOLD_TAG) {
259
+ throw new Error(
260
+ `THRESH: inner ${i}: nested threshold envelopes are not allowed; inner frames are [owner_id, kind_tag, ...payload]`
261
+ );
262
+ }
263
+ throw new Error(
264
+ `THRESH: inner ${i} owner_id 0x${ownerId.toString(16)} is not a u32; inner frames are [owner_id, kind_tag, ...payload] with no V2_SNIP12 tag`
265
+ );
266
+ }
267
+ const inner = [V2_SNIP12_TAG, ...frame];
251
268
  const key = ownerId.toString();
252
269
  if (seenOwners.has(key)) {
253
270
  throw new Error(
@@ -550,6 +567,7 @@ var init_stark = __esm({
550
567
  var execute_paymaster_raw_exports = {};
551
568
  __export(execute_paymaster_raw_exports, {
552
569
  executeShhhSponsoredRaw: () => executeShhhSponsoredRaw,
570
+ newOeNonce: () => newOeNonce,
553
571
  resolveShhhChainId: () => resolveShhhChainId,
554
572
  serializeExecuteFromOutsideV2Calldata: () => serializeExecuteFromOutsideV2Calldata
555
573
  });
@@ -887,13 +905,26 @@ function unwrapPrepareResponse(response) {
887
905
  apiMessage ?? "Invalid response from /transactions/prepare-typed-data: typedData is missing"
888
906
  );
889
907
  }
908
+ function feltEquals(value, expected) {
909
+ try {
910
+ return BigInt(value) === expected;
911
+ } catch {
912
+ return false;
913
+ }
914
+ }
890
915
  function normalizeSignature(signature) {
891
916
  if (Array.isArray(signature)) {
892
917
  if (signature.length < 2) {
893
918
  throw new Error(`Array signature must have at least 2 elements, got ${signature.length}`);
894
919
  }
895
- const r = signature[0];
896
- const s = signature[1];
920
+ const isArgentSingle = signature.length === 5 && feltEquals(signature[0], 1n) && feltEquals(signature[1], 0n);
921
+ if (signature.length !== 2 && !isArgentSingle) {
922
+ throw new Error(
923
+ `Unsupported ${signature.length}-felt signature: expected [r, s] or Argent [1, 0, pubkey, r, s].`
924
+ );
925
+ }
926
+ const r = isArgentSingle ? signature[3] : signature[0];
927
+ const s = isArgentSingle ? signature[4] : signature[1];
897
928
  if (r == null || s == null) {
898
929
  throw new Error(`Signature elements must not be null/undefined. Got r=${r}, s=${s}`);
899
930
  }
@@ -1608,7 +1639,10 @@ var ChipiWallets = class {
1608
1639
  publicKey,
1609
1640
  walletType,
1610
1641
  starkKeyPubAX,
1611
- ...customClassHash && { classHash: customClassHash },
1642
+ // The class the address above was computed with. SHHH always
1643
+ // names it: chipi-back's default for clients that name none is
1644
+ // the class SDKs up to 14.16 used (V8.4), not ours.
1645
+ ...(customClassHash || isShhh) && { classHash: accountClassHash },
1612
1646
  // SHHH: tell chipi-back which signer kind + pubkey felts
1613
1647
  // produced this deployment so it can validate against the
1614
1648
  // expected SHHH constructor shape and populate the new
@@ -1620,6 +1654,11 @@ var ChipiWallets = class {
1620
1654
  }
1621
1655
  });
1622
1656
  const { typedData: typedData2, accountClassHash: accountClassHashResponse } = typedDataResponse;
1657
+ if (isShhh && (!accountClassHashResponse || BigInt(accountClassHashResponse) !== BigInt(accountClassHash))) {
1658
+ throw new Error(
1659
+ `prepare-creation returned class ${accountClassHashResponse ?? "(none)"}, but the wallet address was computed with ${accountClassHash}. Not deploying.`
1660
+ );
1661
+ }
1623
1662
  let userSignaturePayload;
1624
1663
  if (isShhh) {
1625
1664
  userSignaturePayload = {
@@ -2138,14 +2177,14 @@ function normalizeEntrypoints(entrypoints) {
2138
2177
  return entrypoints.map((entry) => {
2139
2178
  const value = String(entry).trim();
2140
2179
  if (HEX_FELT.test(value) || DECIMAL_FELT.test(value)) {
2141
- const felt = BigInt(value);
2142
- if (felt >= FIELD_PRIME) {
2180
+ const felt2 = BigInt(value);
2181
+ if (felt2 >= FIELD_PRIME) {
2143
2182
  throw new shared.ChipiSessionError(
2144
2183
  `Session entrypoint ${value} is not a valid felt (>= field prime).`,
2145
2184
  shared.SESSION_ERRORS.SESSION_ENTRYPOINT_NOT_ALLOWED
2146
2185
  );
2147
2186
  }
2148
- return starknet.num.toHex(felt);
2187
+ return starknet.num.toHex(felt2);
2149
2188
  }
2150
2189
  if (CAIRO_IDENTIFIER.test(value)) {
2151
2190
  return starknet.hash.getSelectorFromName(value);
@@ -3979,6 +4018,504 @@ var signTypedDataArray = async ({
3979
4018
  return [r, s];
3980
4019
  };
3981
4020
 
4021
+ // src/shhh/execute-external-owner.ts
4022
+ init_oe();
4023
+ init_execute_paymaster_raw();
4024
+ init_stark();
4025
+
4026
+ // src/shhh/signers/stark-snip12.ts
4027
+ init_compute_wallet_address();
4028
+ init_oe();
4029
+ var ROLE_OWNER = BigInt(starknet.shortString.encodeShortString("OWNER"));
4030
+ var ROLE_GUARDIAN = BigInt(starknet.shortString.encodeShortString("GUARDIAN"));
4031
+ var OP_ADD_OWNER = BigInt(starknet.shortString.encodeShortString("ADD_OWNER"));
4032
+ var OP_REMOVE_OWNER = BigInt(starknet.shortString.encodeShortString("REMOVE_OWNER"));
4033
+ var OP_ROTATE_OWNER = BigInt(starknet.shortString.encodeShortString("ROTATE_OWNER"));
4034
+ var OP_SET_THRESHOLD = BigInt(starknet.shortString.encodeShortString("SET_THRESHOLD"));
4035
+ var OP_ADD_VERIFIER_CLASS = BigInt(starknet.shortString.encodeShortString("ADD_VERIFIER"));
4036
+ var TIMELOCK_SECONDS = {
4037
+ ADD_OWNER: 172800,
4038
+ // 48h
4039
+ REMOVE_OWNER: 86400,
4040
+ // 24h
4041
+ ROTATE_OWNER: 86400,
4042
+ // 24h
4043
+ SET_THRESHOLD: 172800,
4044
+ // 48h
4045
+ ADD_VERIFIER: 172800,
4046
+ // 48h
4047
+ REMOVE_VERIFIER: 86400,
4048
+ // 24h
4049
+ ADD_GUARDIAN: 86400,
4050
+ // 24h
4051
+ REMOVE_GUARDIAN: 86400,
4052
+ // 24h
4053
+ RECOVERY: 604800
4054
+ // 7d — `TIMELOCK_RECOVERY`, the headline UX gate
4055
+ };
4056
+ var DEFAULT_OP_EXPIRY_SECONDS = 1209600;
4057
+ function _felt2(x, field = "felt") {
4058
+ const v = typeof x === "bigint" ? x : BigInt(x);
4059
+ if (v < 0n) {
4060
+ throw new RangeError(`${field} must be a non-negative felt; got ${v.toString()}`);
4061
+ }
4062
+ return v;
4063
+ }
4064
+ function _encodeOwnerInput(input) {
4065
+ if (input.weight < 0) {
4066
+ throw new RangeError(`NewOwnerInput.weight must be non-negative; got ${input.weight}`);
4067
+ }
4068
+ const kindFelt = _felt2(BigInt(starknet.shortString.encodeShortString(input.kind)), "kind");
4069
+ const roleFelt = input.role === "OWNER" ? ROLE_OWNER : ROLE_GUARDIAN;
4070
+ const pubkey = input.pubkeyBytes.map((p, i) => _felt2(p, `pubkeyBytes[${i}]`));
4071
+ return [
4072
+ kindFelt,
4073
+ BigInt(pubkey.length),
4074
+ ...pubkey,
4075
+ roleFelt,
4076
+ BigInt(input.weight),
4077
+ _felt2(BigInt(starknet.shortString.encodeShortString(input.label)), "label")
4078
+ ];
4079
+ }
4080
+ function _call(walletAddress, entrypoint, calldata) {
4081
+ for (let i = 0; i < calldata.length; i++) {
4082
+ if (calldata[i] < 0n) {
4083
+ throw new RangeError(
4084
+ `calldata[${i}] must be a non-negative felt; got ${calldata[i].toString()}`
4085
+ );
4086
+ }
4087
+ }
4088
+ return {
4089
+ contractAddress: typeof walletAddress === "bigint" ? "0x" + walletAddress.toString(16) : walletAddress,
4090
+ entrypoint,
4091
+ calldata: calldata.map((v) => "0x" + v.toString(16))
4092
+ };
4093
+ }
4094
+ function buildProposeAddOwnerCall(args) {
4095
+ const calldata = [BigInt(args.proposer), ..._encodeOwnerInput(args.newOwner)];
4096
+ return _call(args.walletAddress, "propose_add_owner", calldata);
4097
+ }
4098
+ function buildExecuteAddOwnerCall(args) {
4099
+ const calldata = [_felt2(args.opId), ..._encodeOwnerInput(args.newOwner)];
4100
+ return _call(args.walletAddress, "execute_add_owner", calldata);
4101
+ }
4102
+ function buildProposeRemoveOwnerCall(args) {
4103
+ return _call(args.walletAddress, "propose_remove_owner", [
4104
+ BigInt(args.proposer),
4105
+ BigInt(args.ownerId)
4106
+ ]);
4107
+ }
4108
+ function buildExecuteRemoveOwnerCall(args) {
4109
+ return _call(args.walletAddress, "execute_remove_owner", [
4110
+ _felt2(args.opId),
4111
+ BigInt(args.ownerId)
4112
+ ]);
4113
+ }
4114
+ function buildProposeRotateOwnerCall(args) {
4115
+ return _call(args.walletAddress, "propose_rotate_owner", [
4116
+ BigInt(args.proposer),
4117
+ BigInt(args.ownerId),
4118
+ BigInt(args.newPubkeyBytes.length),
4119
+ ...args.newPubkeyBytes
4120
+ ]);
4121
+ }
4122
+ function buildExecuteRotateOwnerCall(args) {
4123
+ return _call(args.walletAddress, "execute_rotate_owner", [
4124
+ _felt2(args.opId),
4125
+ BigInt(args.ownerId),
4126
+ BigInt(args.newPubkeyBytes.length),
4127
+ ...args.newPubkeyBytes
4128
+ ]);
4129
+ }
4130
+ function buildProposeSetThresholdCall(args) {
4131
+ return _call(args.walletAddress, "propose_set_threshold", [
4132
+ BigInt(args.proposer),
4133
+ BigInt(args.newThreshold)
4134
+ ]);
4135
+ }
4136
+ function buildExecuteSetThresholdCall(args) {
4137
+ return _call(args.walletAddress, "execute_set_threshold", [
4138
+ _felt2(args.opId),
4139
+ BigInt(args.newThreshold)
4140
+ ]);
4141
+ }
4142
+ function buildCancelPendingOpCall(args) {
4143
+ return _call(args.walletAddress, "cancel_pending_op", [_felt2(args.opId)]);
4144
+ }
4145
+ function _verifierClassHash(kind, classHash) {
4146
+ const h = classHash ?? shared.SHHH_VERIFIER_CLASS_HASHES[kind];
4147
+ if (!h) throw new Error(`No verifier class hash known for kind "${kind}".`);
4148
+ return _felt2(h, "classHash");
4149
+ }
4150
+ function buildProposeAddVerifierClassCall(args) {
4151
+ const kindFelt = BigInt(starknet.shortString.encodeShortString(args.kind));
4152
+ return _call(args.walletAddress, "propose_add_verifier_class", [
4153
+ BigInt(args.proposer),
4154
+ kindFelt,
4155
+ _verifierClassHash(args.kind, args.classHash)
4156
+ ]);
4157
+ }
4158
+ function buildExecuteAddVerifierClassCall(args) {
4159
+ const kindFelt = BigInt(starknet.shortString.encodeShortString(args.kind));
4160
+ return _call(args.walletAddress, "execute_add_verifier_class", [
4161
+ _felt2(args.opId),
4162
+ kindFelt,
4163
+ _verifierClassHash(args.kind, args.classHash)
4164
+ ]);
4165
+ }
4166
+ function buildInitiateRecoveryCall(args) {
4167
+ const calldata = [BigInt(args.proposer), ..._encodeOwnerInput(args.newOwner)];
4168
+ return _call(args.walletAddress, "initiate_recovery", calldata);
4169
+ }
4170
+ function buildCancelRecoveryCall(args) {
4171
+ return _call(args.walletAddress, "cancel_recovery", [BigInt(args.ownerId)]);
4172
+ }
4173
+ function buildFinalizeRecoveryCall(args) {
4174
+ return _call(args.walletAddress, "finalize_recovery", _encodeOwnerInput(args.newOwner));
4175
+ }
4176
+ var VIEW_SELECTORS = {
4177
+ get_pending_op: starknet.hash.getSelectorFromName("get_pending_op"),
4178
+ get_pending_recovery: starknet.hash.getSelectorFromName("get_pending_recovery"),
4179
+ get_owner: starknet.hash.getSelectorFromName("get_owner")
4180
+ };
4181
+ function _toSecondsBigInt(value, field) {
4182
+ if (typeof value === "bigint") return value;
4183
+ if (!Number.isFinite(value)) {
4184
+ throw new TypeError(`${field} must be a finite timestamp; got ${value}`);
4185
+ }
4186
+ return BigInt(Math.floor(value));
4187
+ }
4188
+ function isReadyToExecute(validAfterSecs, nowSecs) {
4189
+ return _toSecondsBigInt(nowSecs, "nowSecs") >= _toSecondsBigInt(validAfterSecs, "validAfterSecs");
4190
+ }
4191
+ function secondsUntilExecutable(validAfterSecs, nowSecs) {
4192
+ const remaining = _toSecondsBigInt(validAfterSecs, "validAfterSecs") - _toSecondsBigInt(nowSecs, "nowSecs");
4193
+ return remaining <= 0n ? 0 : Number(remaining);
4194
+ }
4195
+ function _decodeShort(value) {
4196
+ const v = BigInt(value);
4197
+ return v === 0n ? "" : starknet.shortString.decodeShortString(starknet.num.toHex(v));
4198
+ }
4199
+ function _view(provider, walletAddress, entrypoint, calldata = []) {
4200
+ return provider.callContract({
4201
+ contractAddress: typeof walletAddress === "bigint" ? starknet.num.toHex(walletAddress) : walletAddress,
4202
+ entrypoint,
4203
+ calldata: calldata.map((v) => starknet.num.toHex(BigInt(v)))
4204
+ });
4205
+ }
4206
+ async function readShhhOwners(provider, walletAddress) {
4207
+ const [countFelt] = await _view(provider, walletAddress, "owner_count");
4208
+ const count = Number(BigInt(countFelt));
4209
+ const owners = [];
4210
+ for (let id = 0; id < count; id++) {
4211
+ owners.push(decodeShhhOwnerRecord(id, await _view(provider, walletAddress, "get_owner", [id])));
4212
+ }
4213
+ return owners;
4214
+ }
4215
+ function decodeShhhOwnerRecord(ownerId, felts) {
4216
+ if (felts.length < 9) {
4217
+ throw new Error(`get_owner returned ${felts.length} felts; expected 9 (OwnerRecord).`);
4218
+ }
4219
+ return {
4220
+ ownerId,
4221
+ kind: _decodeShort(felts[0]),
4222
+ pubkeyHash: BigInt(felts[1]),
4223
+ role: _decodeShort(felts[4]),
4224
+ weight: Number(BigInt(felts[5])),
4225
+ addedAt: Number(BigInt(felts[6])),
4226
+ label: _decodeShort(felts[7]),
4227
+ revoked: BigInt(felts[8]) !== 0n
4228
+ };
4229
+ }
4230
+ async function readVerifierClass(provider, walletAddress, kind) {
4231
+ const [h] = await _view(provider, walletAddress, "get_verifier_class", [
4232
+ BigInt(starknet.shortString.encodeShortString(kind))
4233
+ ]);
4234
+ return BigInt(h ?? 0);
4235
+ }
4236
+ async function readPendingRecovery(provider, walletAddress) {
4237
+ const r = await _view(provider, walletAddress, "get_pending_recovery");
4238
+ return {
4239
+ initiatedAt: Number(BigInt(r[0])),
4240
+ validAfter: Number(BigInt(r[1])),
4241
+ newOwnerHash: BigInt(r[2]),
4242
+ isActive: BigInt(r[3]) !== 0n
4243
+ };
4244
+ }
4245
+ var OP_PROPOSED_KEY = BigInt(starknet.hash.getSelectorFromName("OpProposed"));
4246
+ function parseOpProposedEvents(events, walletAddress) {
4247
+ const wallet = walletAddress === void 0 ? void 0 : BigInt(walletAddress);
4248
+ return events.filter(
4249
+ (e) => e.keys.length >= 3 && BigInt(e.keys[0]) === OP_PROPOSED_KEY && (wallet === void 0 || e.from_address !== void 0 && BigInt(e.from_address) === wallet)
4250
+ ).map((e) => ({
4251
+ opId: BigInt(e.keys[1]),
4252
+ opKind: _decodeShort(e.keys[2]),
4253
+ proposer: Number(BigInt(e.data[0])),
4254
+ payload: BigInt(e.data[1]),
4255
+ validAfter: Number(BigInt(e.data[2])),
4256
+ expiresAt: Number(BigInt(e.data[3]))
4257
+ }));
4258
+ }
4259
+
4260
+ // src/shhh/signers/stark-snip12.ts
4261
+ var STARK_SNIP12_KIND_TAG = "STARK_SNIP12";
4262
+ var STARK_KIND_TAG_FELT2 = BigInt(starknet.shortString.encodeShortString("STARK"));
4263
+ var V2_SNIP12_FELT = BigInt(starknet.shortString.encodeShortString("V2_SNIP12"));
4264
+ function domainChainId(chainId) {
4265
+ if (typeof chainId === "string" && !chainId.startsWith("0x")) return chainId;
4266
+ return starknet.shortString.decodeShortString(toFeltHex(chainId));
4267
+ }
4268
+ function felt(value) {
4269
+ return BigInt(value);
4270
+ }
4271
+ function starkSnip12ApprovalTypedData(params) {
4272
+ return {
4273
+ types: {
4274
+ StarknetDomain: [
4275
+ { name: "name", type: "shortstring" },
4276
+ { name: "version", type: "shortstring" },
4277
+ { name: "chainId", type: "shortstring" },
4278
+ { name: "revision", type: "shortstring" }
4279
+ ],
4280
+ Approval: [
4281
+ { name: "Wallet", type: "ContractAddress" },
4282
+ { name: "Hash", type: "felt" }
4283
+ ]
4284
+ },
4285
+ primaryType: "Approval",
4286
+ domain: {
4287
+ name: "Shhh",
4288
+ version: "1",
4289
+ chainId: domainChainId(params.chainId ?? "SN_MAIN"),
4290
+ revision: "1"
4291
+ },
4292
+ message: {
4293
+ Wallet: normalizeStarknetAddress(params.walletAddress),
4294
+ Hash: toFeltHex(params.messageHash)
4295
+ }
4296
+ };
4297
+ }
4298
+ function starkSnip12ApprovalHash(params) {
4299
+ const td = starkSnip12ApprovalTypedData(params);
4300
+ return BigInt(starknet.typedData.getMessageHash(td, normalizeStarknetAddress(params.signerAddress)));
4301
+ }
4302
+ function starkSnip12PubkeyFelts(starkPubkey, signerAddress) {
4303
+ const pub = felt(starkPubkey);
4304
+ const account = BigInt(normalizeStarknetAddress(signerAddress));
4305
+ if (pub === 0n || account === 0n) {
4306
+ throw new Error("starkSnip12PubkeyFelts: the key and the account address must be non-zero.");
4307
+ }
4308
+ return [pub, account];
4309
+ }
4310
+ function starkSnip12OwnerCommitment(starkPubkey, signerAddress) {
4311
+ return ownerCommitment(
4312
+ BigInt(starknet.shortString.encodeShortString(STARK_SNIP12_KIND_TAG)),
4313
+ starkSnip12PubkeyFelts(starkPubkey, signerAddress)
4314
+ );
4315
+ }
4316
+ function parseStarknetWalletSignature(signature) {
4317
+ const sig = signature.map((v) => felt(v));
4318
+ if (sig.length === 2) return { r: sig[0], s: sig[1] };
4319
+ if (sig.length === 5 && sig[0] === 1n && sig[1] === 0n) {
4320
+ return { pubkey: sig[2], r: sig[3], s: sig[4] };
4321
+ }
4322
+ if (sig.length === 5 && sig[0] === V2_SNIP12_FELT && sig[2] === STARK_KIND_TAG_FELT2) {
4323
+ return { shhhOwnerId: sig[1], r: sig[3], s: sig[4] };
4324
+ }
4325
+ throw new Error(
4326
+ `This wallet returned a ${sig.length}-felt signature that isn't a single STARK key (multisig, hardware or passkey signers aren't supported as a SHHH co-owner yet).`
4327
+ );
4328
+ }
4329
+ function starkVerifyX(r, s, msgHash, pubkeyX) {
4330
+ const x = pubkeyX.toString(16).padStart(64, "0");
4331
+ const sig = new starknet.ec.starkCurve.Signature(r, s);
4332
+ for (const prefix of ["02", "03"]) {
4333
+ try {
4334
+ if (starknet.ec.starkCurve.verify(sig, toFeltHex(msgHash), prefix + x)) return true;
4335
+ } catch {
4336
+ }
4337
+ }
4338
+ return false;
4339
+ }
4340
+ function verifyStarkSnip12Approval(params) {
4341
+ const { r, s } = parseStarknetWalletSignature(params.signature);
4342
+ const h = starkSnip12ApprovalHash(params);
4343
+ return starkVerifyX(r, s, h, felt(params.starkPubkey));
4344
+ }
4345
+ function buildStarkSnip12Envelope(params) {
4346
+ if (params.ownerIndex < 0n || params.ownerIndex >= 0x100000000n) {
4347
+ throw new Error(
4348
+ `buildStarkSnip12Envelope: ownerIndex ${params.ownerIndex} is out of u32 range. Pass the owner's index in the owner_set, not its commitment.`
4349
+ );
4350
+ }
4351
+ const { r, s } = parseStarknetWalletSignature(params.signature);
4352
+ return wrapV2Snip12Envelope({
4353
+ ownerId: params.ownerIndex,
4354
+ kindTag: STARK_SNIP12_KIND_TAG,
4355
+ payload: [r, s]
4356
+ });
4357
+ }
4358
+ function recoverStarkKeys(r, s, msgHash) {
4359
+ const out = [];
4360
+ for (const bit of [0, 1]) {
4361
+ try {
4362
+ const point = new starknet.ec.starkCurve.Signature(r, s).addRecoveryBit(bit).recoverPublicKey(msgHash.toString(16).padStart(64, "0"));
4363
+ out.push(point.toAffine().x);
4364
+ } catch {
4365
+ }
4366
+ }
4367
+ return out;
4368
+ }
4369
+ async function tryCall(provider, contractAddress, entrypoint, calldata = []) {
4370
+ try {
4371
+ return await provider.callContract({ contractAddress, entrypoint, calldata });
4372
+ } catch {
4373
+ return null;
4374
+ }
4375
+ }
4376
+ async function resolveStarkSnip12Signer(params) {
4377
+ const signer = normalizeStarknetAddress(params.signerAddress);
4378
+ const parsed = parseStarknetWalletSignature(params.signature);
4379
+ const approvalHash = starkSnip12ApprovalHash(params);
4380
+ const candidates = [];
4381
+ if (parsed.pubkey !== void 0) candidates.push(parsed.pubkey);
4382
+ if (parsed.shhhOwnerId !== void 0) {
4383
+ const felts = await tryCall(params.provider, signer, "get_owner", [
4384
+ toFeltHex(parsed.shhhOwnerId)
4385
+ ]);
4386
+ const record = felts && felts.length >= 9 ? decodeShhhOwnerRecord(0, felts) : null;
4387
+ if (record && !record.revoked && record.kind === "STARK" && record.role === "OWNER") {
4388
+ for (const key2 of recoverStarkKeys(parsed.r, parsed.s, approvalHash)) {
4389
+ if (ownerCommitment(STARK_KIND_TAG_FELT2, [key2]) === record.pubkeyHash) candidates.push(key2);
4390
+ }
4391
+ }
4392
+ if (candidates.length === 0) {
4393
+ throw new Error(
4394
+ `Couldn't confirm the Chipi wallet's signer: owner ${parsed.shhhOwnerId} of ${signer} is not an active STARK owner whose key made this signature.`
4395
+ );
4396
+ }
4397
+ }
4398
+ if (params.deploymentData && normalizeStarknetAddress(params.deploymentData.address) === signer) {
4399
+ const cls = normalizeStarknetAddress(params.deploymentData.class_hash);
4400
+ const cd = params.deploymentData.calldata;
4401
+ if (cls === COUNTERFACTUAL_ACCOUNT_CLASSES.OPENZEPPELIN_V3 && cd.length === 1) {
4402
+ candidates.push(felt(cd[0]));
4403
+ }
4404
+ if (cls === COUNTERFACTUAL_ACCOUNT_CLASSES.ARGENT_V0_4 && cd.length === 3) {
4405
+ candidates.push(felt(cd[1]));
4406
+ }
4407
+ }
4408
+ if (candidates.length === 0) {
4409
+ const oz = await tryCall(params.provider, signer, "get_public_key");
4410
+ if (oz && oz.length >= 1) candidates.push(felt(oz[0]));
4411
+ }
4412
+ if (candidates.length === 0) {
4413
+ const signers = await tryCall(params.provider, signer, "get_signers");
4414
+ if (signers && signers.length >= 1) {
4415
+ const starkLen = Number(BigInt(signers[0]));
4416
+ const rest = signers.slice(1 + starkLen);
4417
+ const onlyStark = rest.every((v) => BigInt(v) === 0n);
4418
+ if (starkLen === 1 && onlyStark) candidates.push(felt(signers[1]));
4419
+ }
4420
+ }
4421
+ const key = candidates.find((k) => starkVerifyX(parsed.r, parsed.s, approvalHash, k));
4422
+ if (key === void 0) {
4423
+ throw new Error(
4424
+ "Couldn't confirm which key signs for this wallet. It may use a hardware or passkey signer, a multisig, or an account type we don't read yet."
4425
+ );
4426
+ }
4427
+ return { starkPubkey: key, pubkeyFelts: starkSnip12PubkeyFelts(key, signer) };
4428
+ }
4429
+
4430
+ // src/shhh/execute-external-owner.ts
4431
+ function prepareExternalOwnerExecution(params) {
4432
+ const walletAddress = normalizeStarknetAddress(params.walletAddress);
4433
+ const outsideExecution = buildOutsideExecution({
4434
+ nonce: params.nonce ?? newOeNonce(),
4435
+ calls: params.calls,
4436
+ caller: exports.ANY_CALLER_FELT
4437
+ });
4438
+ const chainId = resolveShhhChainId({ override: params.chainId });
4439
+ const messageHash = computeOeHash(outsideExecution, walletAddress, chainId);
4440
+ const typedData2 = starkSnip12ApprovalTypedData({ walletAddress, messageHash, chainId });
4441
+ return { walletAddress, outsideExecution, messageHash, typedData: typedData2, chainId };
4442
+ }
4443
+ async function submitExternalOwnerExecution(params) {
4444
+ const { prepared } = params;
4445
+ if (params.signer && !verifyStarkSnip12Approval({
4446
+ walletAddress: prepared.walletAddress,
4447
+ messageHash: prepared.messageHash,
4448
+ signerAddress: params.signer.address,
4449
+ starkPubkey: params.signer.starkPubkey,
4450
+ signature: params.signature,
4451
+ chainId: prepared.chainId
4452
+ })) {
4453
+ throw new Error(
4454
+ "The signature doesn't match this wallet's registered key. Sign with the same wallet and account you added."
4455
+ );
4456
+ }
4457
+ const envelope = buildStarkSnip12Envelope({
4458
+ signature: params.signature,
4459
+ ownerIndex: BigInt(params.ownerIndex)
4460
+ });
4461
+ const calldata = serializeExecuteFromOutsideV2Calldata({
4462
+ outsideExecution: prepared.outsideExecution,
4463
+ signature: envelope
4464
+ });
4465
+ const response = await params.client.post({
4466
+ endpoint: "/transactions/execute-sponsored-raw",
4467
+ bearerToken: params.bearerToken,
4468
+ body: {
4469
+ accountAddress: prepared.walletAddress,
4470
+ calldata,
4471
+ ...params.externalUserId ? { externalUserId: params.externalUserId } : {}
4472
+ }
4473
+ });
4474
+ if (!response?.transactionHash) {
4475
+ throw new Error(
4476
+ "execute-sponsored-raw response missing transactionHash. Check the chipi-back logs for upstream paymaster errors."
4477
+ );
4478
+ }
4479
+ return response.transactionHash;
4480
+ }
4481
+ async function executeShhhWithExternalSigner(params) {
4482
+ const prepared = prepareExternalOwnerExecution(params);
4483
+ const signature = await params.signTypedData(prepared.typedData);
4484
+ return submitExternalOwnerExecution({ ...params, prepared, signature });
4485
+ }
4486
+ async function executeShhhWithStarkKey(params) {
4487
+ const walletAddress = normalizeStarknetAddress(params.walletAddress);
4488
+ const outsideExecution = buildOutsideExecution({
4489
+ nonce: params.nonce ?? newOeNonce(),
4490
+ calls: params.calls,
4491
+ caller: exports.ANY_CALLER_FELT
4492
+ });
4493
+ const chainId = resolveShhhChainId({ override: params.chainId });
4494
+ const messageHash = computeOeHash(outsideExecution, walletAddress, chainId);
4495
+ const signature = buildStarkEnvelope({
4496
+ privateKey: params.privateKey,
4497
+ messageHash,
4498
+ ownerIndex: BigInt(params.ownerIndex)
4499
+ });
4500
+ const calldata = serializeExecuteFromOutsideV2Calldata({ outsideExecution, signature });
4501
+ const response = await params.client.post({
4502
+ endpoint: "/transactions/execute-sponsored-raw",
4503
+ bearerToken: params.bearerToken,
4504
+ body: {
4505
+ accountAddress: walletAddress,
4506
+ calldata,
4507
+ signerKind: "STARK",
4508
+ ...params.externalUserId ? { externalUserId: params.externalUserId } : {}
4509
+ }
4510
+ });
4511
+ if (!response?.transactionHash) {
4512
+ throw new Error(
4513
+ "execute-sponsored-raw response missing transactionHash. Check the chipi-back logs for upstream paymaster errors."
4514
+ );
4515
+ }
4516
+ return response.transactionHash;
4517
+ }
4518
+
3982
4519
  // src/chipi-sdk.ts
3983
4520
  var ChipiSDK = class {
3984
4521
  constructor(config) {
@@ -4004,6 +4541,7 @@ var ChipiSDK = class {
4004
4541
  this.getUsdAmount = this.getUsdAmount.bind(this);
4005
4542
  this.signTypedData = this.signTypedData.bind(this);
4006
4543
  this.signTypedDataArray = this.signTypedDataArray.bind(this);
4544
+ this.executeWithExternalSigner = this.executeWithExternalSigner.bind(this);
4007
4545
  this.createPaymasterAdapter = this.createPaymasterAdapter.bind(this);
4008
4546
  this.createX402Facilitator = this.createX402Facilitator.bind(this);
4009
4547
  }
@@ -4140,6 +4678,39 @@ var ChipiSDK = class {
4140
4678
  async signTypedDataArray({ params }) {
4141
4679
  return signTypedDataArray({ params });
4142
4680
  }
4681
+ /**
4682
+ * Run calls on a SHHH wallet, signed by an external Starknet wallet that is
4683
+ * one of its `STARK_SNIP12` owners (Bramble, Braavos, Ready/Argent, OZ, or
4684
+ * another Chipi wallet). The wallet signs an `Approval` typed data through
4685
+ * `signTypedData` (its `wallet_signTypedData`); Chipi's paymaster relays the
4686
+ * outside execution gaslessly. Returns the tx hash: wait for it.
4687
+ *
4688
+ * @example
4689
+ * ```typescript
4690
+ * // Bramble approves an agent session on the user's Chipi wallet.
4691
+ * const bramble = window.starknet_bramble;
4692
+ * const txHash = await sdk.executeWithExternalSigner({
4693
+ * params: {
4694
+ * walletAddress: wallet.publicKey,
4695
+ * ownerIndex: 1, // Bramble's index in the wallet's owner set
4696
+ * calls: buildSessionSetupCalls(wallet.publicKey, sessionConfig, policies),
4697
+ * signTypedData: (typedData) =>
4698
+ * bramble.request({ type: "wallet_signTypedData", params: typedData }),
4699
+ * },
4700
+ * bearerToken,
4701
+ * });
4702
+ * ```
4703
+ */
4704
+ async executeWithExternalSigner({
4705
+ params,
4706
+ bearerToken
4707
+ }) {
4708
+ return executeShhhWithExternalSigner({
4709
+ ...params,
4710
+ client: this.client,
4711
+ bearerToken: this.resolveBearerToken(bearerToken)
4712
+ });
4713
+ }
4143
4714
  /**
4144
4715
  * Transfer tokens
4145
4716
  */
@@ -4689,13 +5260,20 @@ function createStarknetSignInTypedData(params) {
4689
5260
  };
4690
5261
  }
4691
5262
  var MAX_SKEW_SECONDS = 60;
5263
+ var SIWS_CHAIN_ID_FELT = BigInt(starknet.shortString.encodeShortString(SIWS_CHAIN_ID));
5264
+ function isMainnetChainId(chainId) {
5265
+ if (chainId === SIWS_CHAIN_ID) return true;
5266
+ if (typeof chainId === "bigint") return chainId === SIWS_CHAIN_ID_FELT;
5267
+ if (typeof chainId !== "string" || !/^(0x[0-9a-f]+|[0-9]+)$/i.test(chainId)) return false;
5268
+ return BigInt(chainId) === SIWS_CHAIN_ID_FELT;
5269
+ }
4692
5270
  async function verifyStarknetSignIn(params) {
4693
5271
  const { typedData: typedData2, signature, provider, expected, deploymentData } = params;
4694
5272
  const raw = typedData2?.message;
4695
5273
  if (!raw || !Array.isArray(signature) || signature.length === 0) {
4696
5274
  return { ok: false, reason: "MALFORMED" };
4697
5275
  }
4698
- if (typedData2.domain?.chainId !== SIWS_CHAIN_ID) return { ok: false, reason: "WRONG_CHAIN" };
5276
+ if (!isMainnetChainId(typedData2.domain?.chainId)) return { ok: false, reason: "WRONG_CHAIN" };
4699
5277
  let canonical;
4700
5278
  let message;
4701
5279
  try {
@@ -4735,6 +5313,22 @@ init_snip12_hash();
4735
5313
  init_compute_wallet_address();
4736
5314
  init_oe();
4737
5315
  init_stark();
5316
+ function isClassHashNotFound(err) {
5317
+ const e = err;
5318
+ if (e?.baseError?.code === 28 || e?.code === 28) return true;
5319
+ return /class hash not found/i.test(e?.message ?? String(err));
5320
+ }
5321
+ async function isShhhVerifierDeclared(provider, kind, classHash = shared.SHHH_VERIFIER_CLASS_HASHES[kind]) {
5322
+ try {
5323
+ await provider.getClassByHash(classHash);
5324
+ return true;
5325
+ } catch (err) {
5326
+ if (isClassHashNotFound(err)) return false;
5327
+ throw err;
5328
+ }
5329
+ }
5330
+
5331
+ // src/shhh/index.ts
4738
5332
  init_ed25519();
4739
5333
 
4740
5334
  // src/shhh/signers/eip191.ts
@@ -5402,150 +5996,6 @@ async function buildJwtAppleSubEnvelopeFromTestKey(params) {
5402
5996
  });
5403
5997
  return { envelope, pubkey, idToken };
5404
5998
  }
5405
- var ROLE_OWNER = BigInt(starknet.shortString.encodeShortString("OWNER"));
5406
- var ROLE_GUARDIAN = BigInt(starknet.shortString.encodeShortString("GUARDIAN"));
5407
- var OP_ADD_OWNER = BigInt(starknet.shortString.encodeShortString("ADD_OWNER"));
5408
- var OP_REMOVE_OWNER = BigInt(starknet.shortString.encodeShortString("REMOVE_OWNER"));
5409
- var OP_ROTATE_OWNER = BigInt(starknet.shortString.encodeShortString("ROTATE_OWNER"));
5410
- var OP_SET_THRESHOLD = BigInt(starknet.shortString.encodeShortString("SET_THRESHOLD"));
5411
- var TIMELOCK_SECONDS = {
5412
- ADD_OWNER: 172800,
5413
- // 48h
5414
- REMOVE_OWNER: 86400,
5415
- // 24h
5416
- ROTATE_OWNER: 86400,
5417
- // 24h
5418
- SET_THRESHOLD: 172800,
5419
- // 48h
5420
- ADD_VERIFIER: 172800,
5421
- // 48h
5422
- REMOVE_VERIFIER: 86400,
5423
- // 24h
5424
- ADD_GUARDIAN: 86400,
5425
- // 24h
5426
- REMOVE_GUARDIAN: 86400,
5427
- // 24h
5428
- RECOVERY: 604800
5429
- // 7d — `TIMELOCK_RECOVERY`, the headline UX gate
5430
- };
5431
- var DEFAULT_OP_EXPIRY_SECONDS = 1209600;
5432
- function _felt2(x, field = "felt") {
5433
- const v = typeof x === "bigint" ? x : BigInt(x);
5434
- if (v < 0n) {
5435
- throw new RangeError(`${field} must be a non-negative felt; got ${v.toString()}`);
5436
- }
5437
- return v;
5438
- }
5439
- function _encodeOwnerInput(input) {
5440
- if (input.weight < 0) {
5441
- throw new RangeError(`NewOwnerInput.weight must be non-negative; got ${input.weight}`);
5442
- }
5443
- const kindFelt = _felt2(BigInt(starknet.shortString.encodeShortString(input.kind)), "kind");
5444
- const roleFelt = input.role === "OWNER" ? ROLE_OWNER : ROLE_GUARDIAN;
5445
- const pubkey = input.pubkeyBytes.map((p, i) => _felt2(p, `pubkeyBytes[${i}]`));
5446
- return [
5447
- kindFelt,
5448
- BigInt(pubkey.length),
5449
- ...pubkey,
5450
- roleFelt,
5451
- BigInt(input.weight),
5452
- _felt2(BigInt(starknet.shortString.encodeShortString(input.label)), "label")
5453
- ];
5454
- }
5455
- function _call(walletAddress, entrypoint, calldata) {
5456
- for (let i = 0; i < calldata.length; i++) {
5457
- if (calldata[i] < 0n) {
5458
- throw new RangeError(
5459
- `calldata[${i}] must be a non-negative felt; got ${calldata[i].toString()}`
5460
- );
5461
- }
5462
- }
5463
- return {
5464
- contractAddress: typeof walletAddress === "bigint" ? "0x" + walletAddress.toString(16) : walletAddress,
5465
- entrypoint,
5466
- calldata: calldata.map((v) => "0x" + v.toString(16))
5467
- };
5468
- }
5469
- function buildProposeAddOwnerCall(args) {
5470
- const calldata = [BigInt(args.proposer), ..._encodeOwnerInput(args.newOwner)];
5471
- return _call(args.walletAddress, "propose_add_owner", calldata);
5472
- }
5473
- function buildExecuteAddOwnerCall(args) {
5474
- const calldata = [_felt2(args.opId), ..._encodeOwnerInput(args.newOwner)];
5475
- return _call(args.walletAddress, "execute_add_owner", calldata);
5476
- }
5477
- function buildProposeRemoveOwnerCall(args) {
5478
- return _call(args.walletAddress, "propose_remove_owner", [
5479
- BigInt(args.proposer),
5480
- BigInt(args.ownerId)
5481
- ]);
5482
- }
5483
- function buildExecuteRemoveOwnerCall(args) {
5484
- return _call(args.walletAddress, "execute_remove_owner", [
5485
- _felt2(args.opId),
5486
- BigInt(args.ownerId)
5487
- ]);
5488
- }
5489
- function buildProposeRotateOwnerCall(args) {
5490
- return _call(args.walletAddress, "propose_rotate_owner", [
5491
- BigInt(args.proposer),
5492
- BigInt(args.ownerId),
5493
- BigInt(args.newPubkeyBytes.length),
5494
- ...args.newPubkeyBytes
5495
- ]);
5496
- }
5497
- function buildExecuteRotateOwnerCall(args) {
5498
- return _call(args.walletAddress, "execute_rotate_owner", [
5499
- _felt2(args.opId),
5500
- BigInt(args.ownerId),
5501
- BigInt(args.newPubkeyBytes.length),
5502
- ...args.newPubkeyBytes
5503
- ]);
5504
- }
5505
- function buildProposeSetThresholdCall(args) {
5506
- return _call(args.walletAddress, "propose_set_threshold", [
5507
- BigInt(args.proposer),
5508
- BigInt(args.newThreshold)
5509
- ]);
5510
- }
5511
- function buildExecuteSetThresholdCall(args) {
5512
- return _call(args.walletAddress, "execute_set_threshold", [
5513
- _felt2(args.opId),
5514
- BigInt(args.newThreshold)
5515
- ]);
5516
- }
5517
- function buildCancelPendingOpCall(args) {
5518
- return _call(args.walletAddress, "cancel_pending_op", [_felt2(args.opId)]);
5519
- }
5520
- function buildInitiateRecoveryCall(args) {
5521
- const calldata = [BigInt(args.proposer), ..._encodeOwnerInput(args.newOwner)];
5522
- return _call(args.walletAddress, "initiate_recovery", calldata);
5523
- }
5524
- function buildCancelRecoveryCall(args) {
5525
- return _call(args.walletAddress, "cancel_recovery", [BigInt(args.ownerId)]);
5526
- }
5527
- function buildFinalizeRecoveryCall(args) {
5528
- return _call(args.walletAddress, "finalize_recovery", _encodeOwnerInput(args.newOwner));
5529
- }
5530
- var VIEW_SELECTORS = {
5531
- get_pending_op: starknet.hash.getSelectorFromName("get_pending_op"),
5532
- get_pending_recovery: starknet.hash.getSelectorFromName("get_pending_recovery"),
5533
- get_owner: starknet.hash.getSelectorFromName("get_owner")
5534
- };
5535
- function _toSecondsBigInt(value, field) {
5536
- if (typeof value === "bigint") return value;
5537
- if (!Number.isFinite(value)) {
5538
- throw new TypeError(`${field} must be a finite timestamp; got ${value}`);
5539
- }
5540
- return BigInt(Math.floor(value));
5541
- }
5542
- function isReadyToExecute(validAfterSecs, nowSecs) {
5543
- return _toSecondsBigInt(nowSecs, "nowSecs") >= _toSecondsBigInt(validAfterSecs, "validAfterSecs");
5544
- }
5545
- function secondsUntilExecutable(validAfterSecs, nowSecs) {
5546
- const remaining = _toSecondsBigInt(validAfterSecs, "validAfterSecs") - _toSecondsBigInt(nowSecs, "nowSecs");
5547
- return remaining <= 0n ? 0 : Number(remaining);
5548
- }
5549
5999
 
5550
6000
  // src/shhh/index.ts
5551
6001
  init_threshold();
@@ -5656,6 +6106,7 @@ exports.ChipiTreasury = ChipiTreasury;
5656
6106
  exports.ChipiWallets = ChipiWallets;
5657
6107
  exports.DEFAULT_OP_EXPIRY_SECONDS = DEFAULT_OP_EXPIRY_SECONDS;
5658
6108
  exports.OP_ADD_OWNER = OP_ADD_OWNER;
6109
+ exports.OP_ADD_VERIFIER_CLASS = OP_ADD_VERIFIER_CLASS;
5659
6110
  exports.OP_REMOVE_OWNER = OP_REMOVE_OWNER;
5660
6111
  exports.OP_ROTATE_OWNER = OP_ROTATE_OWNER;
5661
6112
  exports.OP_SET_THRESHOLD = OP_SET_THRESHOLD;
@@ -5665,6 +6116,7 @@ exports.SIWS_CHAIN_ID = SIWS_CHAIN_ID;
5665
6116
  exports.SIWS_DOMAIN_NAME = SIWS_DOMAIN_NAME;
5666
6117
  exports.SIWS_DOMAIN_VERSION = SIWS_DOMAIN_VERSION;
5667
6118
  exports.STARKNET_SIGNATURE_VALID = STARKNET_SIGNATURE_VALID;
6119
+ exports.STARK_SNIP12_KIND_TAG = STARK_SNIP12_KIND_TAG;
5668
6120
  exports.SessionTxVerifier = SessionTxVerifier;
5669
6121
  exports.ShhhAccount = ShhhAccount;
5670
6122
  exports.TIMELOCK_SECONDS = TIMELOCK_SECONDS;
@@ -5681,6 +6133,7 @@ exports.buildEd25519EnvelopeFromSignature = buildEd25519EnvelopeFromSignature;
5681
6133
  exports.buildEip191EnvelopeFromPrivateKey = buildEip191EnvelopeFromPrivateKey;
5682
6134
  exports.buildEip191EnvelopeFromSignature = buildEip191EnvelopeFromSignature;
5683
6135
  exports.buildExecuteAddOwnerCall = buildExecuteAddOwnerCall;
6136
+ exports.buildExecuteAddVerifierClassCall = buildExecuteAddVerifierClassCall;
5684
6137
  exports.buildExecuteRemoveOwnerCall = buildExecuteRemoveOwnerCall;
5685
6138
  exports.buildExecuteRotateOwnerCall = buildExecuteRotateOwnerCall;
5686
6139
  exports.buildExecuteSetThresholdCall = buildExecuteSetThresholdCall;
@@ -5691,6 +6144,7 @@ exports.buildJwtAppleSubEnvelopeFromTokenResponse = buildJwtAppleSubEnvelopeFrom
5691
6144
  exports.buildMigrationCalls = buildMigrationCalls;
5692
6145
  exports.buildOutsideExecution = buildOutsideExecution;
5693
6146
  exports.buildProposeAddOwnerCall = buildProposeAddOwnerCall;
6147
+ exports.buildProposeAddVerifierClassCall = buildProposeAddVerifierClassCall;
5694
6148
  exports.buildProposeRemoveOwnerCall = buildProposeRemoveOwnerCall;
5695
6149
  exports.buildProposeRotateOwnerCall = buildProposeRotateOwnerCall;
5696
6150
  exports.buildProposeSetThresholdCall = buildProposeSetThresholdCall;
@@ -5699,6 +6153,7 @@ exports.buildRevokeSessionKeyCall = buildRevokeSessionKeyCall;
5699
6153
  exports.buildSessionSetupCalls = buildSessionSetupCalls;
5700
6154
  exports.buildSetSpendingPolicyCall = buildSetSpendingPolicyCall;
5701
6155
  exports.buildStarkEnvelope = buildStarkEnvelope;
6156
+ exports.buildStarkSnip12Envelope = buildStarkSnip12Envelope;
5702
6157
  exports.buildThresholdEnvelope = buildThresholdEnvelope;
5703
6158
  exports.buildWebAuthnEnvelopeFromAssertion = buildWebAuthnEnvelopeFromAssertion;
5704
6159
  exports.buildWebAuthnEnvelopeFromPrivateKey = buildWebAuthnEnvelopeFromPrivateKey;
@@ -5719,11 +6174,14 @@ exports.eip191OwnerPubkeyParam = eip191OwnerPubkeyParam;
5719
6174
  exports.eip191PubkeyFelts = eip191PubkeyFelts;
5720
6175
  exports.estimateThresholdGasOverhead = estimateThresholdGasOverhead;
5721
6176
  exports.executeShhhSponsoredRaw = executeShhhSponsoredRaw;
6177
+ exports.executeShhhWithExternalSigner = executeShhhWithExternalSigner;
6178
+ exports.executeShhhWithStarkKey = executeShhhWithStarkKey;
5722
6179
  exports.hashCall = hashCall;
5723
6180
  exports.hashCalls = hashCalls;
5724
6181
  exports.hashOutsideExecutionStruct = hashOutsideExecutionStruct;
5725
6182
  exports.hashStarknetDomain = hashStarknetDomain;
5726
6183
  exports.isReadyToExecute = isReadyToExecute;
6184
+ exports.isShhhVerifierDeclared = isShhhVerifierDeclared;
5727
6185
  exports.isThinkDecision = isThinkDecision;
5728
6186
  exports.isValidStarknetSignature = isValidStarknetSignature;
5729
6187
  exports.jwtAppleSubHash = jwtAppleSubHash;
@@ -5739,8 +6197,15 @@ exports.ownerCommitment = ownerCommitment;
5739
6197
  exports.parseAppleIdToken = parseAppleIdToken;
5740
6198
  exports.parseDerEcdsaSignature = parseDerEcdsaSignature;
5741
6199
  exports.parseEip191Signature = parseEip191Signature;
6200
+ exports.parseOpProposedEvents = parseOpProposedEvents;
6201
+ exports.parseStarknetWalletSignature = parseStarknetWalletSignature;
5742
6202
  exports.parseThresholdEnvelope = parseThresholdEnvelope;
6203
+ exports.prepareExternalOwnerExecution = prepareExternalOwnerExecution;
6204
+ exports.readPendingRecovery = readPendingRecovery;
6205
+ exports.readShhhOwners = readShhhOwners;
6206
+ exports.readVerifierClass = readVerifierClass;
5743
6207
  exports.resolveShhhChainId = resolveShhhChainId;
6208
+ exports.resolveStarkSnip12Signer = resolveStarkSnip12Signer;
5744
6209
  exports.secondsUntilExecutable = secondsUntilExecutable;
5745
6210
  exports.serializeExecuteFromOutsideV2Calldata = serializeExecuteFromOutsideV2Calldata;
5746
6211
  exports.signBootstrapMessage = signBootstrapMessage;
@@ -5749,8 +6214,14 @@ exports.signTypedDataArray = signTypedDataArray;
5749
6214
  exports.snip12HashToHexAsciiBytes = snip12HashToHexAsciiBytes;
5750
6215
  exports.starkOwnerId = starkOwnerId;
5751
6216
  exports.starkPubkeyFelts = starkPubkeyFelts;
6217
+ exports.starkSnip12ApprovalHash = starkSnip12ApprovalHash;
6218
+ exports.starkSnip12ApprovalTypedData = starkSnip12ApprovalTypedData;
6219
+ exports.starkSnip12OwnerCommitment = starkSnip12OwnerCommitment;
6220
+ exports.starkSnip12PubkeyFelts = starkSnip12PubkeyFelts;
6221
+ exports.submitExternalOwnerExecution = submitExternalOwnerExecution;
5752
6222
  exports.submitViaAccount = submitViaAccount;
5753
6223
  exports.validateSpendingPolicyConfig = validateSpendingPolicyConfig;
6224
+ exports.verifyStarkSnip12Approval = verifyStarkSnip12Approval;
5754
6225
  exports.verifyStarknetSignIn = verifyStarknetSignIn;
5755
6226
  exports.verifyUndeployedStarknetSignature = verifyUndeployedStarknetSignature;
5756
6227
  exports.waitForTransaction = waitForTransaction;