@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/README.md +48 -0
- package/dist/index.d.mts +396 -67
- package/dist/index.d.ts +396 -67
- package/dist/index.js +632 -161
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +613 -163
- package/dist/index.mjs.map +1 -1
- package/dist/skuPurchases.js +16 -2
- package/dist/skuPurchases.js.map +1 -1
- package/dist/skuPurchases.mjs +16 -2
- package/dist/skuPurchases.mjs.map +1 -1
- package/dist/transactions.js +16 -2
- package/dist/transactions.js.map +1 -1
- package/dist/transactions.mjs +16 -2
- package/dist/transactions.mjs.map +1 -1
- package/dist/wallets.js +25 -3
- package/dist/wallets.js.map +1 -1
- package/dist/wallets.mjs +25 -3
- package/dist/wallets.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { shortString, hash, CallData, ec, RpcProvider, Account, num, CairoCustomEnum, CairoOption, CairoOptionVariant, cairo, typedData, uint256 } from 'starknet';
|
|
2
|
-
import { SHHH_KIND_GAS_OVERHEAD, isValidApiKey, ChipiAuthError, STARKNET_NETWORKS, API_VERSIONING, validateErrorResponse, ChipiApiError, handleApiError, getWalletTypeFromClassHash, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS,
|
|
2
|
+
import { SHHH_VERIFIER_CLASS_HASHES, SHHH_KIND_GAS_OVERHEAD, isValidApiKey, ChipiAuthError, STARKNET_NETWORKS, API_VERSIONING, validateErrorResponse, ChipiApiError, handleApiError, getWalletTypeFromClassHash, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS, API_ENDPOINTS, ChipiTransactionError, formatAmount, SKU_CONTRACTS, CARRIER_IDS, SERVICE_TYPES, ChipiSessionError, SESSION_ERRORS, SESSION_ENTRYPOINTS, SESSION_DEFAULTS, withRpcFallback, CONTRACT_ADDRESSES, TOKEN_DECIMALS } from '@chipi-stack/shared';
|
|
3
3
|
import CryptoES from 'crypto-es';
|
|
4
4
|
import { randomBytes } from 'crypto';
|
|
5
5
|
import { STARKNET_CONTRACTS, Chain } from '@chipi-stack/types';
|
|
@@ -168,9 +168,9 @@ function assertValidV2Snip12Envelope(envelope) {
|
|
|
168
168
|
}
|
|
169
169
|
return envelope[1];
|
|
170
170
|
}
|
|
171
|
-
function _tryDecodeShortString(
|
|
171
|
+
function _tryDecodeShortString(felt2) {
|
|
172
172
|
try {
|
|
173
|
-
return shortString.decodeShortString("0x" +
|
|
173
|
+
return shortString.decodeShortString("0x" + felt2.toString(16));
|
|
174
174
|
} catch {
|
|
175
175
|
return null;
|
|
176
176
|
}
|
|
@@ -194,14 +194,20 @@ function buildThresholdEnvelope(args) {
|
|
|
194
194
|
);
|
|
195
195
|
}
|
|
196
196
|
seenOwners.add(key);
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
if (env.length < 3) {
|
|
198
|
+
throw new Error(
|
|
199
|
+
`THRESH: inner envelope ${i} must have at least [tag, owner_id, kind_tag]; got ${env.length} felts`
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
const frame = env.slice(1);
|
|
203
|
+
out.push(BigInt(frame.length));
|
|
204
|
+
for (const felt2 of frame) {
|
|
205
|
+
if (felt2 < 0n) {
|
|
200
206
|
throw new RangeError(
|
|
201
207
|
`THRESH: envelope ${i} contains negative felt (cannot serialize as felt252)`
|
|
202
208
|
);
|
|
203
209
|
}
|
|
204
|
-
out.push(
|
|
210
|
+
out.push(felt2);
|
|
205
211
|
}
|
|
206
212
|
}
|
|
207
213
|
return out;
|
|
@@ -234,15 +240,26 @@ function parseThresholdEnvelope(envelope) {
|
|
|
234
240
|
`THRESH: inner ${i} would overflow envelope (env_len ${envLen}, cursor ${cursor}, total ${envelope.length})`
|
|
235
241
|
);
|
|
236
242
|
}
|
|
237
|
-
const
|
|
238
|
-
for (const
|
|
239
|
-
if (
|
|
243
|
+
const frame = envelope.slice(cursor, cursor + envLen);
|
|
244
|
+
for (const felt2 of frame) {
|
|
245
|
+
if (felt2 < 0n) {
|
|
240
246
|
throw new RangeError(
|
|
241
247
|
`THRESH: inner ${i} contains negative felt (cannot serialize as felt252)`
|
|
242
248
|
);
|
|
243
249
|
}
|
|
244
250
|
}
|
|
245
|
-
const ownerId =
|
|
251
|
+
const ownerId = frame[0];
|
|
252
|
+
if (ownerId >= 0x100000000n) {
|
|
253
|
+
if (ownerId === V2_THRESHOLD_TAG) {
|
|
254
|
+
throw new Error(
|
|
255
|
+
`THRESH: inner ${i}: nested threshold envelopes are not allowed; inner frames are [owner_id, kind_tag, ...payload]`
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
throw new Error(
|
|
259
|
+
`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`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
const inner = [V2_SNIP12_TAG, ...frame];
|
|
246
263
|
const key = ownerId.toString();
|
|
247
264
|
if (seenOwners.has(key)) {
|
|
248
265
|
throw new Error(
|
|
@@ -545,6 +562,7 @@ var init_stark = __esm({
|
|
|
545
562
|
var execute_paymaster_raw_exports = {};
|
|
546
563
|
__export(execute_paymaster_raw_exports, {
|
|
547
564
|
executeShhhSponsoredRaw: () => executeShhhSponsoredRaw,
|
|
565
|
+
newOeNonce: () => newOeNonce,
|
|
548
566
|
resolveShhhChainId: () => resolveShhhChainId,
|
|
549
567
|
serializeExecuteFromOutsideV2Calldata: () => serializeExecuteFromOutsideV2Calldata
|
|
550
568
|
});
|
|
@@ -882,13 +900,26 @@ function unwrapPrepareResponse(response) {
|
|
|
882
900
|
apiMessage ?? "Invalid response from /transactions/prepare-typed-data: typedData is missing"
|
|
883
901
|
);
|
|
884
902
|
}
|
|
903
|
+
function feltEquals(value, expected) {
|
|
904
|
+
try {
|
|
905
|
+
return BigInt(value) === expected;
|
|
906
|
+
} catch {
|
|
907
|
+
return false;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
885
910
|
function normalizeSignature(signature) {
|
|
886
911
|
if (Array.isArray(signature)) {
|
|
887
912
|
if (signature.length < 2) {
|
|
888
913
|
throw new Error(`Array signature must have at least 2 elements, got ${signature.length}`);
|
|
889
914
|
}
|
|
890
|
-
const
|
|
891
|
-
|
|
915
|
+
const isArgentSingle = signature.length === 5 && feltEquals(signature[0], 1n) && feltEquals(signature[1], 0n);
|
|
916
|
+
if (signature.length !== 2 && !isArgentSingle) {
|
|
917
|
+
throw new Error(
|
|
918
|
+
`Unsupported ${signature.length}-felt signature: expected [r, s] or Argent [1, 0, pubkey, r, s].`
|
|
919
|
+
);
|
|
920
|
+
}
|
|
921
|
+
const r = isArgentSingle ? signature[3] : signature[0];
|
|
922
|
+
const s = isArgentSingle ? signature[4] : signature[1];
|
|
892
923
|
if (r == null || s == null) {
|
|
893
924
|
throw new Error(`Signature elements must not be null/undefined. Got r=${r}, s=${s}`);
|
|
894
925
|
}
|
|
@@ -1603,7 +1634,10 @@ var ChipiWallets = class {
|
|
|
1603
1634
|
publicKey,
|
|
1604
1635
|
walletType,
|
|
1605
1636
|
starkKeyPubAX,
|
|
1606
|
-
|
|
1637
|
+
// The class the address above was computed with. SHHH always
|
|
1638
|
+
// names it: chipi-back's default for clients that name none is
|
|
1639
|
+
// the class SDKs up to 14.16 used (V8.4), not ours.
|
|
1640
|
+
...(customClassHash || isShhh) && { classHash: accountClassHash },
|
|
1607
1641
|
// SHHH: tell chipi-back which signer kind + pubkey felts
|
|
1608
1642
|
// produced this deployment so it can validate against the
|
|
1609
1643
|
// expected SHHH constructor shape and populate the new
|
|
@@ -1615,6 +1649,11 @@ var ChipiWallets = class {
|
|
|
1615
1649
|
}
|
|
1616
1650
|
});
|
|
1617
1651
|
const { typedData: typedData2, accountClassHash: accountClassHashResponse } = typedDataResponse;
|
|
1652
|
+
if (isShhh && (!accountClassHashResponse || BigInt(accountClassHashResponse) !== BigInt(accountClassHash))) {
|
|
1653
|
+
throw new Error(
|
|
1654
|
+
`prepare-creation returned class ${accountClassHashResponse ?? "(none)"}, but the wallet address was computed with ${accountClassHash}. Not deploying.`
|
|
1655
|
+
);
|
|
1656
|
+
}
|
|
1618
1657
|
let userSignaturePayload;
|
|
1619
1658
|
if (isShhh) {
|
|
1620
1659
|
userSignaturePayload = {
|
|
@@ -2133,14 +2172,14 @@ function normalizeEntrypoints(entrypoints) {
|
|
|
2133
2172
|
return entrypoints.map((entry) => {
|
|
2134
2173
|
const value = String(entry).trim();
|
|
2135
2174
|
if (HEX_FELT.test(value) || DECIMAL_FELT.test(value)) {
|
|
2136
|
-
const
|
|
2137
|
-
if (
|
|
2175
|
+
const felt2 = BigInt(value);
|
|
2176
|
+
if (felt2 >= FIELD_PRIME) {
|
|
2138
2177
|
throw new ChipiSessionError(
|
|
2139
2178
|
`Session entrypoint ${value} is not a valid felt (>= field prime).`,
|
|
2140
2179
|
SESSION_ERRORS.SESSION_ENTRYPOINT_NOT_ALLOWED
|
|
2141
2180
|
);
|
|
2142
2181
|
}
|
|
2143
|
-
return num.toHex(
|
|
2182
|
+
return num.toHex(felt2);
|
|
2144
2183
|
}
|
|
2145
2184
|
if (CAIRO_IDENTIFIER.test(value)) {
|
|
2146
2185
|
return hash.getSelectorFromName(value);
|
|
@@ -3974,6 +4013,504 @@ var signTypedDataArray = async ({
|
|
|
3974
4013
|
return [r, s];
|
|
3975
4014
|
};
|
|
3976
4015
|
|
|
4016
|
+
// src/shhh/execute-external-owner.ts
|
|
4017
|
+
init_oe();
|
|
4018
|
+
init_execute_paymaster_raw();
|
|
4019
|
+
init_stark();
|
|
4020
|
+
|
|
4021
|
+
// src/shhh/signers/stark-snip12.ts
|
|
4022
|
+
init_compute_wallet_address();
|
|
4023
|
+
init_oe();
|
|
4024
|
+
var ROLE_OWNER = BigInt(shortString.encodeShortString("OWNER"));
|
|
4025
|
+
var ROLE_GUARDIAN = BigInt(shortString.encodeShortString("GUARDIAN"));
|
|
4026
|
+
var OP_ADD_OWNER = BigInt(shortString.encodeShortString("ADD_OWNER"));
|
|
4027
|
+
var OP_REMOVE_OWNER = BigInt(shortString.encodeShortString("REMOVE_OWNER"));
|
|
4028
|
+
var OP_ROTATE_OWNER = BigInt(shortString.encodeShortString("ROTATE_OWNER"));
|
|
4029
|
+
var OP_SET_THRESHOLD = BigInt(shortString.encodeShortString("SET_THRESHOLD"));
|
|
4030
|
+
var OP_ADD_VERIFIER_CLASS = BigInt(shortString.encodeShortString("ADD_VERIFIER"));
|
|
4031
|
+
var TIMELOCK_SECONDS = {
|
|
4032
|
+
ADD_OWNER: 172800,
|
|
4033
|
+
// 48h
|
|
4034
|
+
REMOVE_OWNER: 86400,
|
|
4035
|
+
// 24h
|
|
4036
|
+
ROTATE_OWNER: 86400,
|
|
4037
|
+
// 24h
|
|
4038
|
+
SET_THRESHOLD: 172800,
|
|
4039
|
+
// 48h
|
|
4040
|
+
ADD_VERIFIER: 172800,
|
|
4041
|
+
// 48h
|
|
4042
|
+
REMOVE_VERIFIER: 86400,
|
|
4043
|
+
// 24h
|
|
4044
|
+
ADD_GUARDIAN: 86400,
|
|
4045
|
+
// 24h
|
|
4046
|
+
REMOVE_GUARDIAN: 86400,
|
|
4047
|
+
// 24h
|
|
4048
|
+
RECOVERY: 604800
|
|
4049
|
+
// 7d — `TIMELOCK_RECOVERY`, the headline UX gate
|
|
4050
|
+
};
|
|
4051
|
+
var DEFAULT_OP_EXPIRY_SECONDS = 1209600;
|
|
4052
|
+
function _felt2(x, field = "felt") {
|
|
4053
|
+
const v = typeof x === "bigint" ? x : BigInt(x);
|
|
4054
|
+
if (v < 0n) {
|
|
4055
|
+
throw new RangeError(`${field} must be a non-negative felt; got ${v.toString()}`);
|
|
4056
|
+
}
|
|
4057
|
+
return v;
|
|
4058
|
+
}
|
|
4059
|
+
function _encodeOwnerInput(input) {
|
|
4060
|
+
if (input.weight < 0) {
|
|
4061
|
+
throw new RangeError(`NewOwnerInput.weight must be non-negative; got ${input.weight}`);
|
|
4062
|
+
}
|
|
4063
|
+
const kindFelt = _felt2(BigInt(shortString.encodeShortString(input.kind)), "kind");
|
|
4064
|
+
const roleFelt = input.role === "OWNER" ? ROLE_OWNER : ROLE_GUARDIAN;
|
|
4065
|
+
const pubkey = input.pubkeyBytes.map((p, i) => _felt2(p, `pubkeyBytes[${i}]`));
|
|
4066
|
+
return [
|
|
4067
|
+
kindFelt,
|
|
4068
|
+
BigInt(pubkey.length),
|
|
4069
|
+
...pubkey,
|
|
4070
|
+
roleFelt,
|
|
4071
|
+
BigInt(input.weight),
|
|
4072
|
+
_felt2(BigInt(shortString.encodeShortString(input.label)), "label")
|
|
4073
|
+
];
|
|
4074
|
+
}
|
|
4075
|
+
function _call(walletAddress, entrypoint, calldata) {
|
|
4076
|
+
for (let i = 0; i < calldata.length; i++) {
|
|
4077
|
+
if (calldata[i] < 0n) {
|
|
4078
|
+
throw new RangeError(
|
|
4079
|
+
`calldata[${i}] must be a non-negative felt; got ${calldata[i].toString()}`
|
|
4080
|
+
);
|
|
4081
|
+
}
|
|
4082
|
+
}
|
|
4083
|
+
return {
|
|
4084
|
+
contractAddress: typeof walletAddress === "bigint" ? "0x" + walletAddress.toString(16) : walletAddress,
|
|
4085
|
+
entrypoint,
|
|
4086
|
+
calldata: calldata.map((v) => "0x" + v.toString(16))
|
|
4087
|
+
};
|
|
4088
|
+
}
|
|
4089
|
+
function buildProposeAddOwnerCall(args) {
|
|
4090
|
+
const calldata = [BigInt(args.proposer), ..._encodeOwnerInput(args.newOwner)];
|
|
4091
|
+
return _call(args.walletAddress, "propose_add_owner", calldata);
|
|
4092
|
+
}
|
|
4093
|
+
function buildExecuteAddOwnerCall(args) {
|
|
4094
|
+
const calldata = [_felt2(args.opId), ..._encodeOwnerInput(args.newOwner)];
|
|
4095
|
+
return _call(args.walletAddress, "execute_add_owner", calldata);
|
|
4096
|
+
}
|
|
4097
|
+
function buildProposeRemoveOwnerCall(args) {
|
|
4098
|
+
return _call(args.walletAddress, "propose_remove_owner", [
|
|
4099
|
+
BigInt(args.proposer),
|
|
4100
|
+
BigInt(args.ownerId)
|
|
4101
|
+
]);
|
|
4102
|
+
}
|
|
4103
|
+
function buildExecuteRemoveOwnerCall(args) {
|
|
4104
|
+
return _call(args.walletAddress, "execute_remove_owner", [
|
|
4105
|
+
_felt2(args.opId),
|
|
4106
|
+
BigInt(args.ownerId)
|
|
4107
|
+
]);
|
|
4108
|
+
}
|
|
4109
|
+
function buildProposeRotateOwnerCall(args) {
|
|
4110
|
+
return _call(args.walletAddress, "propose_rotate_owner", [
|
|
4111
|
+
BigInt(args.proposer),
|
|
4112
|
+
BigInt(args.ownerId),
|
|
4113
|
+
BigInt(args.newPubkeyBytes.length),
|
|
4114
|
+
...args.newPubkeyBytes
|
|
4115
|
+
]);
|
|
4116
|
+
}
|
|
4117
|
+
function buildExecuteRotateOwnerCall(args) {
|
|
4118
|
+
return _call(args.walletAddress, "execute_rotate_owner", [
|
|
4119
|
+
_felt2(args.opId),
|
|
4120
|
+
BigInt(args.ownerId),
|
|
4121
|
+
BigInt(args.newPubkeyBytes.length),
|
|
4122
|
+
...args.newPubkeyBytes
|
|
4123
|
+
]);
|
|
4124
|
+
}
|
|
4125
|
+
function buildProposeSetThresholdCall(args) {
|
|
4126
|
+
return _call(args.walletAddress, "propose_set_threshold", [
|
|
4127
|
+
BigInt(args.proposer),
|
|
4128
|
+
BigInt(args.newThreshold)
|
|
4129
|
+
]);
|
|
4130
|
+
}
|
|
4131
|
+
function buildExecuteSetThresholdCall(args) {
|
|
4132
|
+
return _call(args.walletAddress, "execute_set_threshold", [
|
|
4133
|
+
_felt2(args.opId),
|
|
4134
|
+
BigInt(args.newThreshold)
|
|
4135
|
+
]);
|
|
4136
|
+
}
|
|
4137
|
+
function buildCancelPendingOpCall(args) {
|
|
4138
|
+
return _call(args.walletAddress, "cancel_pending_op", [_felt2(args.opId)]);
|
|
4139
|
+
}
|
|
4140
|
+
function _verifierClassHash(kind, classHash) {
|
|
4141
|
+
const h = classHash ?? SHHH_VERIFIER_CLASS_HASHES[kind];
|
|
4142
|
+
if (!h) throw new Error(`No verifier class hash known for kind "${kind}".`);
|
|
4143
|
+
return _felt2(h, "classHash");
|
|
4144
|
+
}
|
|
4145
|
+
function buildProposeAddVerifierClassCall(args) {
|
|
4146
|
+
const kindFelt = BigInt(shortString.encodeShortString(args.kind));
|
|
4147
|
+
return _call(args.walletAddress, "propose_add_verifier_class", [
|
|
4148
|
+
BigInt(args.proposer),
|
|
4149
|
+
kindFelt,
|
|
4150
|
+
_verifierClassHash(args.kind, args.classHash)
|
|
4151
|
+
]);
|
|
4152
|
+
}
|
|
4153
|
+
function buildExecuteAddVerifierClassCall(args) {
|
|
4154
|
+
const kindFelt = BigInt(shortString.encodeShortString(args.kind));
|
|
4155
|
+
return _call(args.walletAddress, "execute_add_verifier_class", [
|
|
4156
|
+
_felt2(args.opId),
|
|
4157
|
+
kindFelt,
|
|
4158
|
+
_verifierClassHash(args.kind, args.classHash)
|
|
4159
|
+
]);
|
|
4160
|
+
}
|
|
4161
|
+
function buildInitiateRecoveryCall(args) {
|
|
4162
|
+
const calldata = [BigInt(args.proposer), ..._encodeOwnerInput(args.newOwner)];
|
|
4163
|
+
return _call(args.walletAddress, "initiate_recovery", calldata);
|
|
4164
|
+
}
|
|
4165
|
+
function buildCancelRecoveryCall(args) {
|
|
4166
|
+
return _call(args.walletAddress, "cancel_recovery", [BigInt(args.ownerId)]);
|
|
4167
|
+
}
|
|
4168
|
+
function buildFinalizeRecoveryCall(args) {
|
|
4169
|
+
return _call(args.walletAddress, "finalize_recovery", _encodeOwnerInput(args.newOwner));
|
|
4170
|
+
}
|
|
4171
|
+
var VIEW_SELECTORS = {
|
|
4172
|
+
get_pending_op: hash.getSelectorFromName("get_pending_op"),
|
|
4173
|
+
get_pending_recovery: hash.getSelectorFromName("get_pending_recovery"),
|
|
4174
|
+
get_owner: hash.getSelectorFromName("get_owner")
|
|
4175
|
+
};
|
|
4176
|
+
function _toSecondsBigInt(value, field) {
|
|
4177
|
+
if (typeof value === "bigint") return value;
|
|
4178
|
+
if (!Number.isFinite(value)) {
|
|
4179
|
+
throw new TypeError(`${field} must be a finite timestamp; got ${value}`);
|
|
4180
|
+
}
|
|
4181
|
+
return BigInt(Math.floor(value));
|
|
4182
|
+
}
|
|
4183
|
+
function isReadyToExecute(validAfterSecs, nowSecs) {
|
|
4184
|
+
return _toSecondsBigInt(nowSecs, "nowSecs") >= _toSecondsBigInt(validAfterSecs, "validAfterSecs");
|
|
4185
|
+
}
|
|
4186
|
+
function secondsUntilExecutable(validAfterSecs, nowSecs) {
|
|
4187
|
+
const remaining = _toSecondsBigInt(validAfterSecs, "validAfterSecs") - _toSecondsBigInt(nowSecs, "nowSecs");
|
|
4188
|
+
return remaining <= 0n ? 0 : Number(remaining);
|
|
4189
|
+
}
|
|
4190
|
+
function _decodeShort(value) {
|
|
4191
|
+
const v = BigInt(value);
|
|
4192
|
+
return v === 0n ? "" : shortString.decodeShortString(num.toHex(v));
|
|
4193
|
+
}
|
|
4194
|
+
function _view(provider, walletAddress, entrypoint, calldata = []) {
|
|
4195
|
+
return provider.callContract({
|
|
4196
|
+
contractAddress: typeof walletAddress === "bigint" ? num.toHex(walletAddress) : walletAddress,
|
|
4197
|
+
entrypoint,
|
|
4198
|
+
calldata: calldata.map((v) => num.toHex(BigInt(v)))
|
|
4199
|
+
});
|
|
4200
|
+
}
|
|
4201
|
+
async function readShhhOwners(provider, walletAddress) {
|
|
4202
|
+
const [countFelt] = await _view(provider, walletAddress, "owner_count");
|
|
4203
|
+
const count = Number(BigInt(countFelt));
|
|
4204
|
+
const owners = [];
|
|
4205
|
+
for (let id = 0; id < count; id++) {
|
|
4206
|
+
owners.push(decodeShhhOwnerRecord(id, await _view(provider, walletAddress, "get_owner", [id])));
|
|
4207
|
+
}
|
|
4208
|
+
return owners;
|
|
4209
|
+
}
|
|
4210
|
+
function decodeShhhOwnerRecord(ownerId, felts) {
|
|
4211
|
+
if (felts.length < 9) {
|
|
4212
|
+
throw new Error(`get_owner returned ${felts.length} felts; expected 9 (OwnerRecord).`);
|
|
4213
|
+
}
|
|
4214
|
+
return {
|
|
4215
|
+
ownerId,
|
|
4216
|
+
kind: _decodeShort(felts[0]),
|
|
4217
|
+
pubkeyHash: BigInt(felts[1]),
|
|
4218
|
+
role: _decodeShort(felts[4]),
|
|
4219
|
+
weight: Number(BigInt(felts[5])),
|
|
4220
|
+
addedAt: Number(BigInt(felts[6])),
|
|
4221
|
+
label: _decodeShort(felts[7]),
|
|
4222
|
+
revoked: BigInt(felts[8]) !== 0n
|
|
4223
|
+
};
|
|
4224
|
+
}
|
|
4225
|
+
async function readVerifierClass(provider, walletAddress, kind) {
|
|
4226
|
+
const [h] = await _view(provider, walletAddress, "get_verifier_class", [
|
|
4227
|
+
BigInt(shortString.encodeShortString(kind))
|
|
4228
|
+
]);
|
|
4229
|
+
return BigInt(h ?? 0);
|
|
4230
|
+
}
|
|
4231
|
+
async function readPendingRecovery(provider, walletAddress) {
|
|
4232
|
+
const r = await _view(provider, walletAddress, "get_pending_recovery");
|
|
4233
|
+
return {
|
|
4234
|
+
initiatedAt: Number(BigInt(r[0])),
|
|
4235
|
+
validAfter: Number(BigInt(r[1])),
|
|
4236
|
+
newOwnerHash: BigInt(r[2]),
|
|
4237
|
+
isActive: BigInt(r[3]) !== 0n
|
|
4238
|
+
};
|
|
4239
|
+
}
|
|
4240
|
+
var OP_PROPOSED_KEY = BigInt(hash.getSelectorFromName("OpProposed"));
|
|
4241
|
+
function parseOpProposedEvents(events, walletAddress) {
|
|
4242
|
+
const wallet = walletAddress === void 0 ? void 0 : BigInt(walletAddress);
|
|
4243
|
+
return events.filter(
|
|
4244
|
+
(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)
|
|
4245
|
+
).map((e) => ({
|
|
4246
|
+
opId: BigInt(e.keys[1]),
|
|
4247
|
+
opKind: _decodeShort(e.keys[2]),
|
|
4248
|
+
proposer: Number(BigInt(e.data[0])),
|
|
4249
|
+
payload: BigInt(e.data[1]),
|
|
4250
|
+
validAfter: Number(BigInt(e.data[2])),
|
|
4251
|
+
expiresAt: Number(BigInt(e.data[3]))
|
|
4252
|
+
}));
|
|
4253
|
+
}
|
|
4254
|
+
|
|
4255
|
+
// src/shhh/signers/stark-snip12.ts
|
|
4256
|
+
var STARK_SNIP12_KIND_TAG = "STARK_SNIP12";
|
|
4257
|
+
var STARK_KIND_TAG_FELT2 = BigInt(shortString.encodeShortString("STARK"));
|
|
4258
|
+
var V2_SNIP12_FELT = BigInt(shortString.encodeShortString("V2_SNIP12"));
|
|
4259
|
+
function domainChainId(chainId) {
|
|
4260
|
+
if (typeof chainId === "string" && !chainId.startsWith("0x")) return chainId;
|
|
4261
|
+
return shortString.decodeShortString(toFeltHex(chainId));
|
|
4262
|
+
}
|
|
4263
|
+
function felt(value) {
|
|
4264
|
+
return BigInt(value);
|
|
4265
|
+
}
|
|
4266
|
+
function starkSnip12ApprovalTypedData(params) {
|
|
4267
|
+
return {
|
|
4268
|
+
types: {
|
|
4269
|
+
StarknetDomain: [
|
|
4270
|
+
{ name: "name", type: "shortstring" },
|
|
4271
|
+
{ name: "version", type: "shortstring" },
|
|
4272
|
+
{ name: "chainId", type: "shortstring" },
|
|
4273
|
+
{ name: "revision", type: "shortstring" }
|
|
4274
|
+
],
|
|
4275
|
+
Approval: [
|
|
4276
|
+
{ name: "Wallet", type: "ContractAddress" },
|
|
4277
|
+
{ name: "Hash", type: "felt" }
|
|
4278
|
+
]
|
|
4279
|
+
},
|
|
4280
|
+
primaryType: "Approval",
|
|
4281
|
+
domain: {
|
|
4282
|
+
name: "Shhh",
|
|
4283
|
+
version: "1",
|
|
4284
|
+
chainId: domainChainId(params.chainId ?? "SN_MAIN"),
|
|
4285
|
+
revision: "1"
|
|
4286
|
+
},
|
|
4287
|
+
message: {
|
|
4288
|
+
Wallet: normalizeStarknetAddress(params.walletAddress),
|
|
4289
|
+
Hash: toFeltHex(params.messageHash)
|
|
4290
|
+
}
|
|
4291
|
+
};
|
|
4292
|
+
}
|
|
4293
|
+
function starkSnip12ApprovalHash(params) {
|
|
4294
|
+
const td = starkSnip12ApprovalTypedData(params);
|
|
4295
|
+
return BigInt(typedData.getMessageHash(td, normalizeStarknetAddress(params.signerAddress)));
|
|
4296
|
+
}
|
|
4297
|
+
function starkSnip12PubkeyFelts(starkPubkey, signerAddress) {
|
|
4298
|
+
const pub = felt(starkPubkey);
|
|
4299
|
+
const account = BigInt(normalizeStarknetAddress(signerAddress));
|
|
4300
|
+
if (pub === 0n || account === 0n) {
|
|
4301
|
+
throw new Error("starkSnip12PubkeyFelts: the key and the account address must be non-zero.");
|
|
4302
|
+
}
|
|
4303
|
+
return [pub, account];
|
|
4304
|
+
}
|
|
4305
|
+
function starkSnip12OwnerCommitment(starkPubkey, signerAddress) {
|
|
4306
|
+
return ownerCommitment(
|
|
4307
|
+
BigInt(shortString.encodeShortString(STARK_SNIP12_KIND_TAG)),
|
|
4308
|
+
starkSnip12PubkeyFelts(starkPubkey, signerAddress)
|
|
4309
|
+
);
|
|
4310
|
+
}
|
|
4311
|
+
function parseStarknetWalletSignature(signature) {
|
|
4312
|
+
const sig = signature.map((v) => felt(v));
|
|
4313
|
+
if (sig.length === 2) return { r: sig[0], s: sig[1] };
|
|
4314
|
+
if (sig.length === 5 && sig[0] === 1n && sig[1] === 0n) {
|
|
4315
|
+
return { pubkey: sig[2], r: sig[3], s: sig[4] };
|
|
4316
|
+
}
|
|
4317
|
+
if (sig.length === 5 && sig[0] === V2_SNIP12_FELT && sig[2] === STARK_KIND_TAG_FELT2) {
|
|
4318
|
+
return { shhhOwnerId: sig[1], r: sig[3], s: sig[4] };
|
|
4319
|
+
}
|
|
4320
|
+
throw new Error(
|
|
4321
|
+
`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).`
|
|
4322
|
+
);
|
|
4323
|
+
}
|
|
4324
|
+
function starkVerifyX(r, s, msgHash, pubkeyX) {
|
|
4325
|
+
const x = pubkeyX.toString(16).padStart(64, "0");
|
|
4326
|
+
const sig = new ec.starkCurve.Signature(r, s);
|
|
4327
|
+
for (const prefix of ["02", "03"]) {
|
|
4328
|
+
try {
|
|
4329
|
+
if (ec.starkCurve.verify(sig, toFeltHex(msgHash), prefix + x)) return true;
|
|
4330
|
+
} catch {
|
|
4331
|
+
}
|
|
4332
|
+
}
|
|
4333
|
+
return false;
|
|
4334
|
+
}
|
|
4335
|
+
function verifyStarkSnip12Approval(params) {
|
|
4336
|
+
const { r, s } = parseStarknetWalletSignature(params.signature);
|
|
4337
|
+
const h = starkSnip12ApprovalHash(params);
|
|
4338
|
+
return starkVerifyX(r, s, h, felt(params.starkPubkey));
|
|
4339
|
+
}
|
|
4340
|
+
function buildStarkSnip12Envelope(params) {
|
|
4341
|
+
if (params.ownerIndex < 0n || params.ownerIndex >= 0x100000000n) {
|
|
4342
|
+
throw new Error(
|
|
4343
|
+
`buildStarkSnip12Envelope: ownerIndex ${params.ownerIndex} is out of u32 range. Pass the owner's index in the owner_set, not its commitment.`
|
|
4344
|
+
);
|
|
4345
|
+
}
|
|
4346
|
+
const { r, s } = parseStarknetWalletSignature(params.signature);
|
|
4347
|
+
return wrapV2Snip12Envelope({
|
|
4348
|
+
ownerId: params.ownerIndex,
|
|
4349
|
+
kindTag: STARK_SNIP12_KIND_TAG,
|
|
4350
|
+
payload: [r, s]
|
|
4351
|
+
});
|
|
4352
|
+
}
|
|
4353
|
+
function recoverStarkKeys(r, s, msgHash) {
|
|
4354
|
+
const out = [];
|
|
4355
|
+
for (const bit of [0, 1]) {
|
|
4356
|
+
try {
|
|
4357
|
+
const point = new ec.starkCurve.Signature(r, s).addRecoveryBit(bit).recoverPublicKey(msgHash.toString(16).padStart(64, "0"));
|
|
4358
|
+
out.push(point.toAffine().x);
|
|
4359
|
+
} catch {
|
|
4360
|
+
}
|
|
4361
|
+
}
|
|
4362
|
+
return out;
|
|
4363
|
+
}
|
|
4364
|
+
async function tryCall(provider, contractAddress, entrypoint, calldata = []) {
|
|
4365
|
+
try {
|
|
4366
|
+
return await provider.callContract({ contractAddress, entrypoint, calldata });
|
|
4367
|
+
} catch {
|
|
4368
|
+
return null;
|
|
4369
|
+
}
|
|
4370
|
+
}
|
|
4371
|
+
async function resolveStarkSnip12Signer(params) {
|
|
4372
|
+
const signer = normalizeStarknetAddress(params.signerAddress);
|
|
4373
|
+
const parsed = parseStarknetWalletSignature(params.signature);
|
|
4374
|
+
const approvalHash = starkSnip12ApprovalHash(params);
|
|
4375
|
+
const candidates = [];
|
|
4376
|
+
if (parsed.pubkey !== void 0) candidates.push(parsed.pubkey);
|
|
4377
|
+
if (parsed.shhhOwnerId !== void 0) {
|
|
4378
|
+
const felts = await tryCall(params.provider, signer, "get_owner", [
|
|
4379
|
+
toFeltHex(parsed.shhhOwnerId)
|
|
4380
|
+
]);
|
|
4381
|
+
const record = felts && felts.length >= 9 ? decodeShhhOwnerRecord(0, felts) : null;
|
|
4382
|
+
if (record && !record.revoked && record.kind === "STARK" && record.role === "OWNER") {
|
|
4383
|
+
for (const key2 of recoverStarkKeys(parsed.r, parsed.s, approvalHash)) {
|
|
4384
|
+
if (ownerCommitment(STARK_KIND_TAG_FELT2, [key2]) === record.pubkeyHash) candidates.push(key2);
|
|
4385
|
+
}
|
|
4386
|
+
}
|
|
4387
|
+
if (candidates.length === 0) {
|
|
4388
|
+
throw new Error(
|
|
4389
|
+
`Couldn't confirm the Chipi wallet's signer: owner ${parsed.shhhOwnerId} of ${signer} is not an active STARK owner whose key made this signature.`
|
|
4390
|
+
);
|
|
4391
|
+
}
|
|
4392
|
+
}
|
|
4393
|
+
if (params.deploymentData && normalizeStarknetAddress(params.deploymentData.address) === signer) {
|
|
4394
|
+
const cls = normalizeStarknetAddress(params.deploymentData.class_hash);
|
|
4395
|
+
const cd = params.deploymentData.calldata;
|
|
4396
|
+
if (cls === COUNTERFACTUAL_ACCOUNT_CLASSES.OPENZEPPELIN_V3 && cd.length === 1) {
|
|
4397
|
+
candidates.push(felt(cd[0]));
|
|
4398
|
+
}
|
|
4399
|
+
if (cls === COUNTERFACTUAL_ACCOUNT_CLASSES.ARGENT_V0_4 && cd.length === 3) {
|
|
4400
|
+
candidates.push(felt(cd[1]));
|
|
4401
|
+
}
|
|
4402
|
+
}
|
|
4403
|
+
if (candidates.length === 0) {
|
|
4404
|
+
const oz = await tryCall(params.provider, signer, "get_public_key");
|
|
4405
|
+
if (oz && oz.length >= 1) candidates.push(felt(oz[0]));
|
|
4406
|
+
}
|
|
4407
|
+
if (candidates.length === 0) {
|
|
4408
|
+
const signers = await tryCall(params.provider, signer, "get_signers");
|
|
4409
|
+
if (signers && signers.length >= 1) {
|
|
4410
|
+
const starkLen = Number(BigInt(signers[0]));
|
|
4411
|
+
const rest = signers.slice(1 + starkLen);
|
|
4412
|
+
const onlyStark = rest.every((v) => BigInt(v) === 0n);
|
|
4413
|
+
if (starkLen === 1 && onlyStark) candidates.push(felt(signers[1]));
|
|
4414
|
+
}
|
|
4415
|
+
}
|
|
4416
|
+
const key = candidates.find((k) => starkVerifyX(parsed.r, parsed.s, approvalHash, k));
|
|
4417
|
+
if (key === void 0) {
|
|
4418
|
+
throw new Error(
|
|
4419
|
+
"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."
|
|
4420
|
+
);
|
|
4421
|
+
}
|
|
4422
|
+
return { starkPubkey: key, pubkeyFelts: starkSnip12PubkeyFelts(key, signer) };
|
|
4423
|
+
}
|
|
4424
|
+
|
|
4425
|
+
// src/shhh/execute-external-owner.ts
|
|
4426
|
+
function prepareExternalOwnerExecution(params) {
|
|
4427
|
+
const walletAddress = normalizeStarknetAddress(params.walletAddress);
|
|
4428
|
+
const outsideExecution = buildOutsideExecution({
|
|
4429
|
+
nonce: params.nonce ?? newOeNonce(),
|
|
4430
|
+
calls: params.calls,
|
|
4431
|
+
caller: ANY_CALLER_FELT
|
|
4432
|
+
});
|
|
4433
|
+
const chainId = resolveShhhChainId({ override: params.chainId });
|
|
4434
|
+
const messageHash = computeOeHash(outsideExecution, walletAddress, chainId);
|
|
4435
|
+
const typedData2 = starkSnip12ApprovalTypedData({ walletAddress, messageHash, chainId });
|
|
4436
|
+
return { walletAddress, outsideExecution, messageHash, typedData: typedData2, chainId };
|
|
4437
|
+
}
|
|
4438
|
+
async function submitExternalOwnerExecution(params) {
|
|
4439
|
+
const { prepared } = params;
|
|
4440
|
+
if (params.signer && !verifyStarkSnip12Approval({
|
|
4441
|
+
walletAddress: prepared.walletAddress,
|
|
4442
|
+
messageHash: prepared.messageHash,
|
|
4443
|
+
signerAddress: params.signer.address,
|
|
4444
|
+
starkPubkey: params.signer.starkPubkey,
|
|
4445
|
+
signature: params.signature,
|
|
4446
|
+
chainId: prepared.chainId
|
|
4447
|
+
})) {
|
|
4448
|
+
throw new Error(
|
|
4449
|
+
"The signature doesn't match this wallet's registered key. Sign with the same wallet and account you added."
|
|
4450
|
+
);
|
|
4451
|
+
}
|
|
4452
|
+
const envelope = buildStarkSnip12Envelope({
|
|
4453
|
+
signature: params.signature,
|
|
4454
|
+
ownerIndex: BigInt(params.ownerIndex)
|
|
4455
|
+
});
|
|
4456
|
+
const calldata = serializeExecuteFromOutsideV2Calldata({
|
|
4457
|
+
outsideExecution: prepared.outsideExecution,
|
|
4458
|
+
signature: envelope
|
|
4459
|
+
});
|
|
4460
|
+
const response = await params.client.post({
|
|
4461
|
+
endpoint: "/transactions/execute-sponsored-raw",
|
|
4462
|
+
bearerToken: params.bearerToken,
|
|
4463
|
+
body: {
|
|
4464
|
+
accountAddress: prepared.walletAddress,
|
|
4465
|
+
calldata,
|
|
4466
|
+
...params.externalUserId ? { externalUserId: params.externalUserId } : {}
|
|
4467
|
+
}
|
|
4468
|
+
});
|
|
4469
|
+
if (!response?.transactionHash) {
|
|
4470
|
+
throw new Error(
|
|
4471
|
+
"execute-sponsored-raw response missing transactionHash. Check the chipi-back logs for upstream paymaster errors."
|
|
4472
|
+
);
|
|
4473
|
+
}
|
|
4474
|
+
return response.transactionHash;
|
|
4475
|
+
}
|
|
4476
|
+
async function executeShhhWithExternalSigner(params) {
|
|
4477
|
+
const prepared = prepareExternalOwnerExecution(params);
|
|
4478
|
+
const signature = await params.signTypedData(prepared.typedData);
|
|
4479
|
+
return submitExternalOwnerExecution({ ...params, prepared, signature });
|
|
4480
|
+
}
|
|
4481
|
+
async function executeShhhWithStarkKey(params) {
|
|
4482
|
+
const walletAddress = normalizeStarknetAddress(params.walletAddress);
|
|
4483
|
+
const outsideExecution = buildOutsideExecution({
|
|
4484
|
+
nonce: params.nonce ?? newOeNonce(),
|
|
4485
|
+
calls: params.calls,
|
|
4486
|
+
caller: ANY_CALLER_FELT
|
|
4487
|
+
});
|
|
4488
|
+
const chainId = resolveShhhChainId({ override: params.chainId });
|
|
4489
|
+
const messageHash = computeOeHash(outsideExecution, walletAddress, chainId);
|
|
4490
|
+
const signature = buildStarkEnvelope({
|
|
4491
|
+
privateKey: params.privateKey,
|
|
4492
|
+
messageHash,
|
|
4493
|
+
ownerIndex: BigInt(params.ownerIndex)
|
|
4494
|
+
});
|
|
4495
|
+
const calldata = serializeExecuteFromOutsideV2Calldata({ outsideExecution, signature });
|
|
4496
|
+
const response = await params.client.post({
|
|
4497
|
+
endpoint: "/transactions/execute-sponsored-raw",
|
|
4498
|
+
bearerToken: params.bearerToken,
|
|
4499
|
+
body: {
|
|
4500
|
+
accountAddress: walletAddress,
|
|
4501
|
+
calldata,
|
|
4502
|
+
signerKind: "STARK",
|
|
4503
|
+
...params.externalUserId ? { externalUserId: params.externalUserId } : {}
|
|
4504
|
+
}
|
|
4505
|
+
});
|
|
4506
|
+
if (!response?.transactionHash) {
|
|
4507
|
+
throw new Error(
|
|
4508
|
+
"execute-sponsored-raw response missing transactionHash. Check the chipi-back logs for upstream paymaster errors."
|
|
4509
|
+
);
|
|
4510
|
+
}
|
|
4511
|
+
return response.transactionHash;
|
|
4512
|
+
}
|
|
4513
|
+
|
|
3977
4514
|
// src/chipi-sdk.ts
|
|
3978
4515
|
var ChipiSDK = class {
|
|
3979
4516
|
constructor(config) {
|
|
@@ -3999,6 +4536,7 @@ var ChipiSDK = class {
|
|
|
3999
4536
|
this.getUsdAmount = this.getUsdAmount.bind(this);
|
|
4000
4537
|
this.signTypedData = this.signTypedData.bind(this);
|
|
4001
4538
|
this.signTypedDataArray = this.signTypedDataArray.bind(this);
|
|
4539
|
+
this.executeWithExternalSigner = this.executeWithExternalSigner.bind(this);
|
|
4002
4540
|
this.createPaymasterAdapter = this.createPaymasterAdapter.bind(this);
|
|
4003
4541
|
this.createX402Facilitator = this.createX402Facilitator.bind(this);
|
|
4004
4542
|
}
|
|
@@ -4135,6 +4673,39 @@ var ChipiSDK = class {
|
|
|
4135
4673
|
async signTypedDataArray({ params }) {
|
|
4136
4674
|
return signTypedDataArray({ params });
|
|
4137
4675
|
}
|
|
4676
|
+
/**
|
|
4677
|
+
* Run calls on a SHHH wallet, signed by an external Starknet wallet that is
|
|
4678
|
+
* one of its `STARK_SNIP12` owners (Bramble, Braavos, Ready/Argent, OZ, or
|
|
4679
|
+
* another Chipi wallet). The wallet signs an `Approval` typed data through
|
|
4680
|
+
* `signTypedData` (its `wallet_signTypedData`); Chipi's paymaster relays the
|
|
4681
|
+
* outside execution gaslessly. Returns the tx hash: wait for it.
|
|
4682
|
+
*
|
|
4683
|
+
* @example
|
|
4684
|
+
* ```typescript
|
|
4685
|
+
* // Bramble approves an agent session on the user's Chipi wallet.
|
|
4686
|
+
* const bramble = window.starknet_bramble;
|
|
4687
|
+
* const txHash = await sdk.executeWithExternalSigner({
|
|
4688
|
+
* params: {
|
|
4689
|
+
* walletAddress: wallet.publicKey,
|
|
4690
|
+
* ownerIndex: 1, // Bramble's index in the wallet's owner set
|
|
4691
|
+
* calls: buildSessionSetupCalls(wallet.publicKey, sessionConfig, policies),
|
|
4692
|
+
* signTypedData: (typedData) =>
|
|
4693
|
+
* bramble.request({ type: "wallet_signTypedData", params: typedData }),
|
|
4694
|
+
* },
|
|
4695
|
+
* bearerToken,
|
|
4696
|
+
* });
|
|
4697
|
+
* ```
|
|
4698
|
+
*/
|
|
4699
|
+
async executeWithExternalSigner({
|
|
4700
|
+
params,
|
|
4701
|
+
bearerToken
|
|
4702
|
+
}) {
|
|
4703
|
+
return executeShhhWithExternalSigner({
|
|
4704
|
+
...params,
|
|
4705
|
+
client: this.client,
|
|
4706
|
+
bearerToken: this.resolveBearerToken(bearerToken)
|
|
4707
|
+
});
|
|
4708
|
+
}
|
|
4138
4709
|
/**
|
|
4139
4710
|
* Transfer tokens
|
|
4140
4711
|
*/
|
|
@@ -4684,13 +5255,20 @@ function createStarknetSignInTypedData(params) {
|
|
|
4684
5255
|
};
|
|
4685
5256
|
}
|
|
4686
5257
|
var MAX_SKEW_SECONDS = 60;
|
|
5258
|
+
var SIWS_CHAIN_ID_FELT = BigInt(shortString.encodeShortString(SIWS_CHAIN_ID));
|
|
5259
|
+
function isMainnetChainId(chainId) {
|
|
5260
|
+
if (chainId === SIWS_CHAIN_ID) return true;
|
|
5261
|
+
if (typeof chainId === "bigint") return chainId === SIWS_CHAIN_ID_FELT;
|
|
5262
|
+
if (typeof chainId !== "string" || !/^(0x[0-9a-f]+|[0-9]+)$/i.test(chainId)) return false;
|
|
5263
|
+
return BigInt(chainId) === SIWS_CHAIN_ID_FELT;
|
|
5264
|
+
}
|
|
4687
5265
|
async function verifyStarknetSignIn(params) {
|
|
4688
5266
|
const { typedData: typedData2, signature, provider, expected, deploymentData } = params;
|
|
4689
5267
|
const raw = typedData2?.message;
|
|
4690
5268
|
if (!raw || !Array.isArray(signature) || signature.length === 0) {
|
|
4691
5269
|
return { ok: false, reason: "MALFORMED" };
|
|
4692
5270
|
}
|
|
4693
|
-
if (typedData2.domain?.chainId
|
|
5271
|
+
if (!isMainnetChainId(typedData2.domain?.chainId)) return { ok: false, reason: "WRONG_CHAIN" };
|
|
4694
5272
|
let canonical;
|
|
4695
5273
|
let message;
|
|
4696
5274
|
try {
|
|
@@ -4730,6 +5308,22 @@ init_snip12_hash();
|
|
|
4730
5308
|
init_compute_wallet_address();
|
|
4731
5309
|
init_oe();
|
|
4732
5310
|
init_stark();
|
|
5311
|
+
function isClassHashNotFound(err) {
|
|
5312
|
+
const e = err;
|
|
5313
|
+
if (e?.baseError?.code === 28 || e?.code === 28) return true;
|
|
5314
|
+
return /class hash not found/i.test(e?.message ?? String(err));
|
|
5315
|
+
}
|
|
5316
|
+
async function isShhhVerifierDeclared(provider, kind, classHash = SHHH_VERIFIER_CLASS_HASHES[kind]) {
|
|
5317
|
+
try {
|
|
5318
|
+
await provider.getClassByHash(classHash);
|
|
5319
|
+
return true;
|
|
5320
|
+
} catch (err) {
|
|
5321
|
+
if (isClassHashNotFound(err)) return false;
|
|
5322
|
+
throw err;
|
|
5323
|
+
}
|
|
5324
|
+
}
|
|
5325
|
+
|
|
5326
|
+
// src/shhh/index.ts
|
|
4733
5327
|
init_ed25519();
|
|
4734
5328
|
|
|
4735
5329
|
// src/shhh/signers/eip191.ts
|
|
@@ -5397,150 +5991,6 @@ async function buildJwtAppleSubEnvelopeFromTestKey(params) {
|
|
|
5397
5991
|
});
|
|
5398
5992
|
return { envelope, pubkey, idToken };
|
|
5399
5993
|
}
|
|
5400
|
-
var ROLE_OWNER = BigInt(shortString.encodeShortString("OWNER"));
|
|
5401
|
-
var ROLE_GUARDIAN = BigInt(shortString.encodeShortString("GUARDIAN"));
|
|
5402
|
-
var OP_ADD_OWNER = BigInt(shortString.encodeShortString("ADD_OWNER"));
|
|
5403
|
-
var OP_REMOVE_OWNER = BigInt(shortString.encodeShortString("REMOVE_OWNER"));
|
|
5404
|
-
var OP_ROTATE_OWNER = BigInt(shortString.encodeShortString("ROTATE_OWNER"));
|
|
5405
|
-
var OP_SET_THRESHOLD = BigInt(shortString.encodeShortString("SET_THRESHOLD"));
|
|
5406
|
-
var TIMELOCK_SECONDS = {
|
|
5407
|
-
ADD_OWNER: 172800,
|
|
5408
|
-
// 48h
|
|
5409
|
-
REMOVE_OWNER: 86400,
|
|
5410
|
-
// 24h
|
|
5411
|
-
ROTATE_OWNER: 86400,
|
|
5412
|
-
// 24h
|
|
5413
|
-
SET_THRESHOLD: 172800,
|
|
5414
|
-
// 48h
|
|
5415
|
-
ADD_VERIFIER: 172800,
|
|
5416
|
-
// 48h
|
|
5417
|
-
REMOVE_VERIFIER: 86400,
|
|
5418
|
-
// 24h
|
|
5419
|
-
ADD_GUARDIAN: 86400,
|
|
5420
|
-
// 24h
|
|
5421
|
-
REMOVE_GUARDIAN: 86400,
|
|
5422
|
-
// 24h
|
|
5423
|
-
RECOVERY: 604800
|
|
5424
|
-
// 7d — `TIMELOCK_RECOVERY`, the headline UX gate
|
|
5425
|
-
};
|
|
5426
|
-
var DEFAULT_OP_EXPIRY_SECONDS = 1209600;
|
|
5427
|
-
function _felt2(x, field = "felt") {
|
|
5428
|
-
const v = typeof x === "bigint" ? x : BigInt(x);
|
|
5429
|
-
if (v < 0n) {
|
|
5430
|
-
throw new RangeError(`${field} must be a non-negative felt; got ${v.toString()}`);
|
|
5431
|
-
}
|
|
5432
|
-
return v;
|
|
5433
|
-
}
|
|
5434
|
-
function _encodeOwnerInput(input) {
|
|
5435
|
-
if (input.weight < 0) {
|
|
5436
|
-
throw new RangeError(`NewOwnerInput.weight must be non-negative; got ${input.weight}`);
|
|
5437
|
-
}
|
|
5438
|
-
const kindFelt = _felt2(BigInt(shortString.encodeShortString(input.kind)), "kind");
|
|
5439
|
-
const roleFelt = input.role === "OWNER" ? ROLE_OWNER : ROLE_GUARDIAN;
|
|
5440
|
-
const pubkey = input.pubkeyBytes.map((p, i) => _felt2(p, `pubkeyBytes[${i}]`));
|
|
5441
|
-
return [
|
|
5442
|
-
kindFelt,
|
|
5443
|
-
BigInt(pubkey.length),
|
|
5444
|
-
...pubkey,
|
|
5445
|
-
roleFelt,
|
|
5446
|
-
BigInt(input.weight),
|
|
5447
|
-
_felt2(BigInt(shortString.encodeShortString(input.label)), "label")
|
|
5448
|
-
];
|
|
5449
|
-
}
|
|
5450
|
-
function _call(walletAddress, entrypoint, calldata) {
|
|
5451
|
-
for (let i = 0; i < calldata.length; i++) {
|
|
5452
|
-
if (calldata[i] < 0n) {
|
|
5453
|
-
throw new RangeError(
|
|
5454
|
-
`calldata[${i}] must be a non-negative felt; got ${calldata[i].toString()}`
|
|
5455
|
-
);
|
|
5456
|
-
}
|
|
5457
|
-
}
|
|
5458
|
-
return {
|
|
5459
|
-
contractAddress: typeof walletAddress === "bigint" ? "0x" + walletAddress.toString(16) : walletAddress,
|
|
5460
|
-
entrypoint,
|
|
5461
|
-
calldata: calldata.map((v) => "0x" + v.toString(16))
|
|
5462
|
-
};
|
|
5463
|
-
}
|
|
5464
|
-
function buildProposeAddOwnerCall(args) {
|
|
5465
|
-
const calldata = [BigInt(args.proposer), ..._encodeOwnerInput(args.newOwner)];
|
|
5466
|
-
return _call(args.walletAddress, "propose_add_owner", calldata);
|
|
5467
|
-
}
|
|
5468
|
-
function buildExecuteAddOwnerCall(args) {
|
|
5469
|
-
const calldata = [_felt2(args.opId), ..._encodeOwnerInput(args.newOwner)];
|
|
5470
|
-
return _call(args.walletAddress, "execute_add_owner", calldata);
|
|
5471
|
-
}
|
|
5472
|
-
function buildProposeRemoveOwnerCall(args) {
|
|
5473
|
-
return _call(args.walletAddress, "propose_remove_owner", [
|
|
5474
|
-
BigInt(args.proposer),
|
|
5475
|
-
BigInt(args.ownerId)
|
|
5476
|
-
]);
|
|
5477
|
-
}
|
|
5478
|
-
function buildExecuteRemoveOwnerCall(args) {
|
|
5479
|
-
return _call(args.walletAddress, "execute_remove_owner", [
|
|
5480
|
-
_felt2(args.opId),
|
|
5481
|
-
BigInt(args.ownerId)
|
|
5482
|
-
]);
|
|
5483
|
-
}
|
|
5484
|
-
function buildProposeRotateOwnerCall(args) {
|
|
5485
|
-
return _call(args.walletAddress, "propose_rotate_owner", [
|
|
5486
|
-
BigInt(args.proposer),
|
|
5487
|
-
BigInt(args.ownerId),
|
|
5488
|
-
BigInt(args.newPubkeyBytes.length),
|
|
5489
|
-
...args.newPubkeyBytes
|
|
5490
|
-
]);
|
|
5491
|
-
}
|
|
5492
|
-
function buildExecuteRotateOwnerCall(args) {
|
|
5493
|
-
return _call(args.walletAddress, "execute_rotate_owner", [
|
|
5494
|
-
_felt2(args.opId),
|
|
5495
|
-
BigInt(args.ownerId),
|
|
5496
|
-
BigInt(args.newPubkeyBytes.length),
|
|
5497
|
-
...args.newPubkeyBytes
|
|
5498
|
-
]);
|
|
5499
|
-
}
|
|
5500
|
-
function buildProposeSetThresholdCall(args) {
|
|
5501
|
-
return _call(args.walletAddress, "propose_set_threshold", [
|
|
5502
|
-
BigInt(args.proposer),
|
|
5503
|
-
BigInt(args.newThreshold)
|
|
5504
|
-
]);
|
|
5505
|
-
}
|
|
5506
|
-
function buildExecuteSetThresholdCall(args) {
|
|
5507
|
-
return _call(args.walletAddress, "execute_set_threshold", [
|
|
5508
|
-
_felt2(args.opId),
|
|
5509
|
-
BigInt(args.newThreshold)
|
|
5510
|
-
]);
|
|
5511
|
-
}
|
|
5512
|
-
function buildCancelPendingOpCall(args) {
|
|
5513
|
-
return _call(args.walletAddress, "cancel_pending_op", [_felt2(args.opId)]);
|
|
5514
|
-
}
|
|
5515
|
-
function buildInitiateRecoveryCall(args) {
|
|
5516
|
-
const calldata = [BigInt(args.proposer), ..._encodeOwnerInput(args.newOwner)];
|
|
5517
|
-
return _call(args.walletAddress, "initiate_recovery", calldata);
|
|
5518
|
-
}
|
|
5519
|
-
function buildCancelRecoveryCall(args) {
|
|
5520
|
-
return _call(args.walletAddress, "cancel_recovery", [BigInt(args.ownerId)]);
|
|
5521
|
-
}
|
|
5522
|
-
function buildFinalizeRecoveryCall(args) {
|
|
5523
|
-
return _call(args.walletAddress, "finalize_recovery", _encodeOwnerInput(args.newOwner));
|
|
5524
|
-
}
|
|
5525
|
-
var VIEW_SELECTORS = {
|
|
5526
|
-
get_pending_op: hash.getSelectorFromName("get_pending_op"),
|
|
5527
|
-
get_pending_recovery: hash.getSelectorFromName("get_pending_recovery"),
|
|
5528
|
-
get_owner: hash.getSelectorFromName("get_owner")
|
|
5529
|
-
};
|
|
5530
|
-
function _toSecondsBigInt(value, field) {
|
|
5531
|
-
if (typeof value === "bigint") return value;
|
|
5532
|
-
if (!Number.isFinite(value)) {
|
|
5533
|
-
throw new TypeError(`${field} must be a finite timestamp; got ${value}`);
|
|
5534
|
-
}
|
|
5535
|
-
return BigInt(Math.floor(value));
|
|
5536
|
-
}
|
|
5537
|
-
function isReadyToExecute(validAfterSecs, nowSecs) {
|
|
5538
|
-
return _toSecondsBigInt(nowSecs, "nowSecs") >= _toSecondsBigInt(validAfterSecs, "validAfterSecs");
|
|
5539
|
-
}
|
|
5540
|
-
function secondsUntilExecutable(validAfterSecs, nowSecs) {
|
|
5541
|
-
const remaining = _toSecondsBigInt(validAfterSecs, "validAfterSecs") - _toSecondsBigInt(nowSecs, "nowSecs");
|
|
5542
|
-
return remaining <= 0n ? 0 : Number(remaining);
|
|
5543
|
-
}
|
|
5544
5994
|
|
|
5545
5995
|
// src/shhh/index.ts
|
|
5546
5996
|
init_threshold();
|
|
@@ -5622,6 +6072,6 @@ function submitViaAccount(funded) {
|
|
|
5622
6072
|
};
|
|
5623
6073
|
}
|
|
5624
6074
|
|
|
5625
|
-
export { ANY_CALLER_FELT, APPLE_ISSUER, BOOTSTRAP_DOMAIN_SEPARATOR, COUNTERFACTUAL_ACCOUNT_CLASSES, ChipiAi, 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, SIWS_CHAIN_ID, SIWS_DOMAIN_NAME, SIWS_DOMAIN_VERSION, STARKNET_MESSAGE_PREFIX, STARKNET_SIGNATURE_VALID, SessionTxVerifier, ShhhAccount, TIMELOCK_SECONDS, VIEW_SELECTORS, X402Facilitator, X402ShhhClient, assertValidV2Snip12Envelope, buildAddSessionKeyCall, buildBootstrapSignedCall, buildCancelPendingOpCall, buildCancelRecoveryCall, buildEd25519Envelope, buildEd25519EnvelopeFromSignature, buildEip191EnvelopeFromPrivateKey, buildEip191EnvelopeFromSignature, buildExecuteAddOwnerCall, buildExecuteRemoveOwnerCall, buildExecuteRotateOwnerCall, buildExecuteSetThresholdCall, buildFinalizeRecoveryCall, buildInitiateRecoveryCall, buildJwtAppleSubEnvelopeFromTestKey, buildJwtAppleSubEnvelopeFromTokenResponse, buildMigrationCalls, buildOutsideExecution, buildProposeAddOwnerCall, buildProposeRemoveOwnerCall, buildProposeRotateOwnerCall, buildProposeSetThresholdCall, buildRemoveSpendingPolicyCall, buildRevokeSessionKeyCall, buildSessionSetupCalls, buildSetSpendingPolicyCall, buildStarkEnvelope, buildThresholdEnvelope, buildWebAuthnEnvelopeFromAssertion, buildWebAuthnEnvelopeFromPrivateKey, byteArrayToFelts, computeAddressSalt, computeBootstrapMessage, computeISignerId, computeOeHash, computeShhhAddress, computeSnip12Hash, createStarknetSignInTypedData, decryptPrivateKey, ed25519OwnerId, ed25519OwnerPubkeyParam, ed25519PubkeyFelts, ed25519SignedBytes, eip191OwnerId, eip191OwnerPubkeyParam, eip191PubkeyFelts, encryptPrivateKey, estimateThresholdGasOverhead, executeShhhSponsoredRaw, hashCall, hashCalls, hashOutsideExecutionStruct, hashStarknetDomain, isReadyToExecute, isThinkDecision, isValidStarknetSignature, jwtAppleSubHash, jwtAppleSubOwnerId, jwtAppleSubPubkeyFelts, labelToFelt, locateSubClaim, messageHashToNonceB64url, migrateChipiWalletToShhh, normalizeEntrypoints, normalizeStarknetAddress, ownerCommitment, parseAppleIdToken, parseDerEcdsaSignature, parseEip191Signature, parseThresholdEnvelope, resolveShhhChainId, secondsUntilExecutable, serializeExecuteFromOutsideV2Calldata, signBootstrapMessage, signTypedData, signTypedDataArray, snip12HashToHexAsciiBytes, starkOwnerId, starkPubkeyFelts, submitViaAccount, validateSpendingPolicyConfig, verifyStarknetSignIn, verifyUndeployedStarknetSignature, waitForTransaction, webauthnOwnerId, webauthnOwnerPubkeyParam, webauthnPubkeyFelts, wrapV2Snip12Envelope, wrapV2ThresholdEnvelope, x402Middleware };
|
|
6075
|
+
export { ANY_CALLER_FELT, APPLE_ISSUER, BOOTSTRAP_DOMAIN_SEPARATOR, COUNTERFACTUAL_ACCOUNT_CLASSES, ChipiAi, 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_ADD_VERIFIER_CLASS, 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, SIWS_CHAIN_ID, SIWS_DOMAIN_NAME, SIWS_DOMAIN_VERSION, STARKNET_MESSAGE_PREFIX, STARKNET_SIGNATURE_VALID, STARK_SNIP12_KIND_TAG, SessionTxVerifier, ShhhAccount, TIMELOCK_SECONDS, VIEW_SELECTORS, X402Facilitator, X402ShhhClient, assertValidV2Snip12Envelope, buildAddSessionKeyCall, buildBootstrapSignedCall, buildCancelPendingOpCall, buildCancelRecoveryCall, buildEd25519Envelope, buildEd25519EnvelopeFromSignature, buildEip191EnvelopeFromPrivateKey, buildEip191EnvelopeFromSignature, buildExecuteAddOwnerCall, buildExecuteAddVerifierClassCall, buildExecuteRemoveOwnerCall, buildExecuteRotateOwnerCall, buildExecuteSetThresholdCall, buildFinalizeRecoveryCall, buildInitiateRecoveryCall, buildJwtAppleSubEnvelopeFromTestKey, buildJwtAppleSubEnvelopeFromTokenResponse, buildMigrationCalls, buildOutsideExecution, buildProposeAddOwnerCall, buildProposeAddVerifierClassCall, buildProposeRemoveOwnerCall, buildProposeRotateOwnerCall, buildProposeSetThresholdCall, buildRemoveSpendingPolicyCall, buildRevokeSessionKeyCall, buildSessionSetupCalls, buildSetSpendingPolicyCall, buildStarkEnvelope, buildStarkSnip12Envelope, buildThresholdEnvelope, buildWebAuthnEnvelopeFromAssertion, buildWebAuthnEnvelopeFromPrivateKey, byteArrayToFelts, computeAddressSalt, computeBootstrapMessage, computeISignerId, computeOeHash, computeShhhAddress, computeSnip12Hash, createStarknetSignInTypedData, decryptPrivateKey, ed25519OwnerId, ed25519OwnerPubkeyParam, ed25519PubkeyFelts, ed25519SignedBytes, eip191OwnerId, eip191OwnerPubkeyParam, eip191PubkeyFelts, encryptPrivateKey, estimateThresholdGasOverhead, executeShhhSponsoredRaw, executeShhhWithExternalSigner, executeShhhWithStarkKey, hashCall, hashCalls, hashOutsideExecutionStruct, hashStarknetDomain, isReadyToExecute, isShhhVerifierDeclared, isThinkDecision, isValidStarknetSignature, jwtAppleSubHash, jwtAppleSubOwnerId, jwtAppleSubPubkeyFelts, labelToFelt, locateSubClaim, messageHashToNonceB64url, migrateChipiWalletToShhh, normalizeEntrypoints, normalizeStarknetAddress, ownerCommitment, parseAppleIdToken, parseDerEcdsaSignature, parseEip191Signature, parseOpProposedEvents, parseStarknetWalletSignature, parseThresholdEnvelope, prepareExternalOwnerExecution, readPendingRecovery, readShhhOwners, readVerifierClass, resolveShhhChainId, resolveStarkSnip12Signer, secondsUntilExecutable, serializeExecuteFromOutsideV2Calldata, signBootstrapMessage, signTypedData, signTypedDataArray, snip12HashToHexAsciiBytes, starkOwnerId, starkPubkeyFelts, starkSnip12ApprovalHash, starkSnip12ApprovalTypedData, starkSnip12OwnerCommitment, starkSnip12PubkeyFelts, submitExternalOwnerExecution, submitViaAccount, validateSpendingPolicyConfig, verifyStarkSnip12Approval, verifyStarknetSignIn, verifyUndeployedStarknetSignature, waitForTransaction, webauthnOwnerId, webauthnOwnerPubkeyParam, webauthnPubkeyFelts, wrapV2Snip12Envelope, wrapV2ThresholdEnvelope, x402Middleware };
|
|
5626
6076
|
//# sourceMappingURL=index.mjs.map
|
|
5627
6077
|
//# sourceMappingURL=index.mjs.map
|