@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.js
CHANGED
|
@@ -173,9 +173,9 @@ function assertValidV2Snip12Envelope(envelope) {
|
|
|
173
173
|
}
|
|
174
174
|
return envelope[1];
|
|
175
175
|
}
|
|
176
|
-
function _tryDecodeShortString(
|
|
176
|
+
function _tryDecodeShortString(felt2) {
|
|
177
177
|
try {
|
|
178
|
-
return starknet.shortString.decodeShortString("0x" +
|
|
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
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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(
|
|
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
|
|
243
|
-
for (const
|
|
244
|
-
if (
|
|
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 =
|
|
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
|
|
896
|
-
|
|
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
|
-
|
|
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
|
|
2142
|
-
if (
|
|
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(
|
|
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
|
|
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;
|