@chipi-stack/chipi-react 14.15.1 → 14.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks.d.mts +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +91 -19
- package/dist/hooks.js.map +1 -1
- package/dist/hooks.mjs +91 -20
- package/dist/hooks.mjs.map +1 -1
- package/dist/{index-gNLTF6ix.d.mts → index-CUfzUBgv.d.mts} +92 -12
- package/dist/{index-gNLTF6ix.d.ts → index-CUfzUBgv.d.ts} +92 -12
- package/dist/index.d.mts +16 -3
- package/dist/index.d.ts +16 -3
- package/dist/index.js +159 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +159 -32
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1340,6 +1340,22 @@ function useSignTypedData() {
|
|
|
1340
1340
|
reset: mutation.reset
|
|
1341
1341
|
};
|
|
1342
1342
|
}
|
|
1343
|
+
function useExternalSignerExecute() {
|
|
1344
|
+
const { chipiSDK } = useChipiContext();
|
|
1345
|
+
const mutation = reactQuery.useMutation({
|
|
1346
|
+
mutationFn: async (input) => chipiSDK.executeWithExternalSigner(input)
|
|
1347
|
+
});
|
|
1348
|
+
return {
|
|
1349
|
+
execute: mutation.mutate,
|
|
1350
|
+
executeAsync: mutation.mutateAsync,
|
|
1351
|
+
data: mutation.data,
|
|
1352
|
+
isLoading: mutation.isPending,
|
|
1353
|
+
isError: mutation.isError,
|
|
1354
|
+
error: mutation.error,
|
|
1355
|
+
isSuccess: mutation.isSuccess,
|
|
1356
|
+
reset: mutation.reset
|
|
1357
|
+
};
|
|
1358
|
+
}
|
|
1343
1359
|
|
|
1344
1360
|
// ../node_modules/.pnpm/@starknet-io+types-js@0.9.2/node_modules/@starknet-io/types-js/dist/esm/index.js
|
|
1345
1361
|
var esm_exports = {};
|
|
@@ -20418,6 +20434,41 @@ function hexEq(a, b) {
|
|
|
20418
20434
|
return a === b;
|
|
20419
20435
|
}
|
|
20420
20436
|
}
|
|
20437
|
+
function parseCapAmount(value, field, token) {
|
|
20438
|
+
try {
|
|
20439
|
+
const v = typeof value === "bigint" ? value : BigInt(String(value).trim());
|
|
20440
|
+
if (v < 0n) throw new Error("negative");
|
|
20441
|
+
return v;
|
|
20442
|
+
} catch {
|
|
20443
|
+
throw new Error(
|
|
20444
|
+
`session_spend_cap_invalid: ${field} for token ${token} must be a non-negative integer in base units (got "${String(value)}")`
|
|
20445
|
+
);
|
|
20446
|
+
}
|
|
20447
|
+
}
|
|
20448
|
+
function toSpendingPolicies(caps, lifetimeSeconds) {
|
|
20449
|
+
return caps.map((cap) => {
|
|
20450
|
+
const policy = "maxPerWindow" in cap ? {
|
|
20451
|
+
token: cap.token,
|
|
20452
|
+
maxPerCall: parseCapAmount(cap.maxPerCall, "maxPerCall", cap.token),
|
|
20453
|
+
maxPerWindow: parseCapAmount(cap.maxPerWindow, "maxPerWindow", cap.token),
|
|
20454
|
+
windowSeconds: cap.windowSeconds
|
|
20455
|
+
} : (() => {
|
|
20456
|
+
const amount = parseCapAmount(cap.amount, "amount", cap.token);
|
|
20457
|
+
return {
|
|
20458
|
+
token: cap.token,
|
|
20459
|
+
maxPerCall: amount,
|
|
20460
|
+
maxPerWindow: amount,
|
|
20461
|
+
windowSeconds: Math.max(1, lifetimeSeconds)
|
|
20462
|
+
};
|
|
20463
|
+
})();
|
|
20464
|
+
if (policy.maxPerWindow === 0n) {
|
|
20465
|
+
throw new Error(
|
|
20466
|
+
`session_spend_cap_zero: the cap for token ${cap.token} resolves to maxPerWindow = 0, which means unlimited on-chain. Use a positive cap.`
|
|
20467
|
+
);
|
|
20468
|
+
}
|
|
20469
|
+
return policy;
|
|
20470
|
+
});
|
|
20471
|
+
}
|
|
20421
20472
|
function sessionCovers(policy, calls) {
|
|
20422
20473
|
if (!policy?.allowedCalls?.length) return false;
|
|
20423
20474
|
return calls.every(
|
|
@@ -20432,6 +20483,10 @@ function useChipiWalletObject(config3) {
|
|
|
20432
20483
|
const { signTypedDataAsync } = useSignTypedData();
|
|
20433
20484
|
const { createSessionKeyAsync } = useCreateSessionKey();
|
|
20434
20485
|
const { addSessionKeyToContractAsync } = useAddSessionKeyToContract();
|
|
20486
|
+
const { chipiSDK } = useChipiContext();
|
|
20487
|
+
const sdk = React.useRef(chipiSDK);
|
|
20488
|
+
sdk.current = chipiSDK;
|
|
20489
|
+
const warnedMissingApproval = React.useRef(false);
|
|
20435
20490
|
const cfg = React.useRef(config3);
|
|
20436
20491
|
cfg.current = config3;
|
|
20437
20492
|
const requireWallet = () => {
|
|
@@ -20444,28 +20499,33 @@ function useChipiWalletObject(config3) {
|
|
|
20444
20499
|
if (policy.validUntil <= nowSec()) throw new Error("session_policy_expired");
|
|
20445
20500
|
const c = cfg.current;
|
|
20446
20501
|
const wallet = requireWallet();
|
|
20502
|
+
const lifetimeSeconds = Math.max(1, policy.validUntil - nowSec());
|
|
20503
|
+
const spendingPolicies = policy.spendCaps?.length ? toSpendingPolicies(policy.spendCaps, lifetimeSeconds) : [];
|
|
20447
20504
|
const encryptKey = await c.getEncryptKey();
|
|
20448
20505
|
const session = await createSessionKeyAsync({
|
|
20449
20506
|
encryptKey,
|
|
20450
|
-
durationSeconds:
|
|
20507
|
+
durationSeconds: lifetimeSeconds
|
|
20451
20508
|
});
|
|
20452
20509
|
const bearerToken = await c.getBearerToken();
|
|
20453
|
-
|
|
20454
|
-
|
|
20455
|
-
|
|
20456
|
-
|
|
20457
|
-
|
|
20458
|
-
|
|
20459
|
-
|
|
20460
|
-
|
|
20461
|
-
|
|
20462
|
-
|
|
20463
|
-
|
|
20464
|
-
|
|
20465
|
-
|
|
20466
|
-
|
|
20467
|
-
|
|
20468
|
-
|
|
20510
|
+
const params = {
|
|
20511
|
+
encryptKey,
|
|
20512
|
+
wallet,
|
|
20513
|
+
sessionConfig: {
|
|
20514
|
+
sessionPublicKey: session.publicKey,
|
|
20515
|
+
validUntil: policy.validUntil,
|
|
20516
|
+
maxCalls: 1e3,
|
|
20517
|
+
// Selectors; empty = all entrypoints allowed. On-chain this is a
|
|
20518
|
+
// per-selector whitelist, NOT scoped to allowedCalls' contracts.
|
|
20519
|
+
allowedEntrypoints: policy.allowedCalls.map(
|
|
20520
|
+
(a) => hash_exports.getSelectorFromName(a.entrypoint)
|
|
20521
|
+
)
|
|
20522
|
+
}
|
|
20523
|
+
};
|
|
20524
|
+
if (spendingPolicies.length > 0) {
|
|
20525
|
+
await sdk.current.sessions.setupSession({ ...params, spendingPolicies }, bearerToken);
|
|
20526
|
+
} else {
|
|
20527
|
+
await addSessionKeyToContractAsync({ params, bearerToken });
|
|
20528
|
+
}
|
|
20469
20529
|
return session;
|
|
20470
20530
|
},
|
|
20471
20531
|
[createSessionKeyAsync, addSessionKeyToContractAsync]
|
|
@@ -20505,12 +20565,23 @@ function useChipiWalletObject(config3) {
|
|
|
20505
20565
|
return signTypedDataAsync({ encryptKey, wallet, typedData });
|
|
20506
20566
|
},
|
|
20507
20567
|
getDeploymentData: async () => {
|
|
20508
|
-
throw new Error("account_already_deployed");
|
|
20568
|
+
if (cfg.current.isDeployed === true) throw new Error("account_already_deployed");
|
|
20569
|
+
throw new Error("account_deployment_data_unavailable");
|
|
20509
20570
|
},
|
|
20510
20571
|
createSession: async (policy) => {
|
|
20511
20572
|
await createSession(policy);
|
|
20512
20573
|
},
|
|
20513
|
-
requestApproval: (req) =>
|
|
20574
|
+
requestApproval: (req) => {
|
|
20575
|
+
const gate = cfg.current.requestApproval;
|
|
20576
|
+
if (gate) return gate(req);
|
|
20577
|
+
if (!warnedMissingApproval.current) {
|
|
20578
|
+
warnedMissingApproval.current = true;
|
|
20579
|
+
console.warn(
|
|
20580
|
+
"[ChipiSDK:Connect] No `requestApproval` was provided to useChipiWalletObject, so every approval (connect, execute, signTypedData, session) is denied. Pass `requestApproval` to show the user an approval UI and resolve true/false."
|
|
20581
|
+
);
|
|
20582
|
+
}
|
|
20583
|
+
return Promise.resolve(false);
|
|
20584
|
+
}
|
|
20514
20585
|
}),
|
|
20515
20586
|
[callAnyContractAsync, executeWithSessionAsync, signTypedDataAsync, createSession]
|
|
20516
20587
|
);
|
|
@@ -21189,11 +21260,35 @@ var RpcError2 = class extends Error {
|
|
|
21189
21260
|
var USER_REFUSED_OP = 113;
|
|
21190
21261
|
var INVALID_REQUEST_PAYLOAD = 114;
|
|
21191
21262
|
var ACCOUNT_ALREADY_DEPLOYED = 115;
|
|
21263
|
+
var NO_DEPLOYMENT_DATA = 116;
|
|
21192
21264
|
var UNKNOWN_ERROR = 163;
|
|
21265
|
+
var MISSING_APPROVAL_WARNING = "[ChipiSDK:Connect] No `requestApproval` was provided, so every approval (connect, execute, signTypedData, session) is denied. Pass `requestApproval` to show the user an approval UI and resolve true/false.";
|
|
21266
|
+
function normalizeChainId(value) {
|
|
21267
|
+
try {
|
|
21268
|
+
if (typeof value === "bigint") return value;
|
|
21269
|
+
if (typeof value === "number") {
|
|
21270
|
+
return Number.isSafeInteger(value) && value >= 0 ? BigInt(value) : null;
|
|
21271
|
+
}
|
|
21272
|
+
if (typeof value !== "string" || value.length === 0) return null;
|
|
21273
|
+
if (/^0x[0-9a-f]+$/i.test(value) || /^[0-9]+$/.test(value)) return BigInt(value);
|
|
21274
|
+
return BigInt(shortString_exports.encodeShortString(value));
|
|
21275
|
+
} catch {
|
|
21276
|
+
return null;
|
|
21277
|
+
}
|
|
21278
|
+
}
|
|
21193
21279
|
function createChipiWindowObject(deps) {
|
|
21194
21280
|
const accountListeners = /* @__PURE__ */ new Set();
|
|
21195
21281
|
const networkListeners = /* @__PURE__ */ new Set();
|
|
21196
|
-
|
|
21282
|
+
let approved = false;
|
|
21283
|
+
let pendingConnect = null;
|
|
21284
|
+
let warnedMissingApproval = false;
|
|
21285
|
+
const approve = deps.requestApproval ?? (async () => {
|
|
21286
|
+
if (!warnedMissingApproval) {
|
|
21287
|
+
warnedMissingApproval = true;
|
|
21288
|
+
console.warn(MISSING_APPROVAL_WARNING);
|
|
21289
|
+
}
|
|
21290
|
+
return false;
|
|
21291
|
+
});
|
|
21197
21292
|
async function requireApproval(req) {
|
|
21198
21293
|
const ok = await approve(req);
|
|
21199
21294
|
if (!ok) throw new RpcError2(USER_REFUSED_OP, "User refused the operation");
|
|
@@ -21201,19 +21296,27 @@ function createChipiWindowObject(deps) {
|
|
|
21201
21296
|
const request = (async (call) => {
|
|
21202
21297
|
switch (call.type) {
|
|
21203
21298
|
case "wallet_requestAccounts": {
|
|
21204
|
-
|
|
21205
|
-
|
|
21206
|
-
await requireApproval({ type: "connect" });
|
|
21207
|
-
return deps.getAccounts();
|
|
21299
|
+
if (call.params?.silent_mode) {
|
|
21300
|
+
return approved ? deps.getAccounts() : [];
|
|
21208
21301
|
}
|
|
21209
|
-
|
|
21302
|
+
if (approved) {
|
|
21303
|
+
const accounts = await deps.getAccounts();
|
|
21304
|
+
if (accounts.length > 0) return accounts;
|
|
21305
|
+
}
|
|
21306
|
+
if (!pendingConnect) {
|
|
21307
|
+
pendingConnect = requireApproval({ type: "connect" }).then(() => {
|
|
21308
|
+
approved = true;
|
|
21309
|
+
}).finally(() => {
|
|
21310
|
+
pendingConnect = null;
|
|
21311
|
+
});
|
|
21312
|
+
}
|
|
21313
|
+
await pendingConnect;
|
|
21314
|
+
return deps.getAccounts();
|
|
21210
21315
|
}
|
|
21211
21316
|
case "wallet_requestChainId":
|
|
21212
21317
|
return deps.chainId;
|
|
21213
|
-
case "wallet_getPermissions":
|
|
21214
|
-
|
|
21215
|
-
return accounts.length > 0 ? ["accounts"] : [];
|
|
21216
|
-
}
|
|
21318
|
+
case "wallet_getPermissions":
|
|
21319
|
+
return approved ? ["accounts"] : [];
|
|
21217
21320
|
case "wallet_addInvokeTransaction": {
|
|
21218
21321
|
const wireCalls = call.params?.calls ?? [];
|
|
21219
21322
|
if (wireCalls.length === 0) {
|
|
@@ -21226,14 +21329,38 @@ function createChipiWindowObject(deps) {
|
|
|
21226
21329
|
}
|
|
21227
21330
|
case "wallet_signTypedData": {
|
|
21228
21331
|
const typedData = call.params;
|
|
21332
|
+
const domainChainId = typedData?.domain?.chainId;
|
|
21333
|
+
if (domainChainId === void 0 || domainChainId === null) {
|
|
21334
|
+
throw new RpcError2(
|
|
21335
|
+
INVALID_REQUEST_PAYLOAD,
|
|
21336
|
+
`wallet_signTypedData: domain.chainId is required (the wallet chain is ${deps.chainId})`
|
|
21337
|
+
);
|
|
21338
|
+
}
|
|
21339
|
+
const expected = normalizeChainId(deps.chainId);
|
|
21340
|
+
const actual = normalizeChainId(domainChainId);
|
|
21341
|
+
if (actual === null || expected === null || actual !== expected) {
|
|
21342
|
+
throw new RpcError2(
|
|
21343
|
+
INVALID_REQUEST_PAYLOAD,
|
|
21344
|
+
`wallet_signTypedData: domain.chainId ${String(domainChainId)} does not match the wallet chain ${deps.chainId}`
|
|
21345
|
+
);
|
|
21346
|
+
}
|
|
21229
21347
|
await requireApproval({ type: "signTypedData", typedData });
|
|
21230
21348
|
return deps.signTypedData(typedData);
|
|
21231
21349
|
}
|
|
21232
21350
|
case "wallet_deploymentData":
|
|
21233
21351
|
try {
|
|
21234
21352
|
return await deps.getDeploymentData();
|
|
21235
|
-
} catch {
|
|
21236
|
-
|
|
21353
|
+
} catch (err2) {
|
|
21354
|
+
if (err2 instanceof Error && err2.message === "account_already_deployed") {
|
|
21355
|
+
throw new RpcError2(ACCOUNT_ALREADY_DEPLOYED, "Account already deployed");
|
|
21356
|
+
}
|
|
21357
|
+
if (err2 instanceof Error && err2.message === "account_deployment_data_unavailable") {
|
|
21358
|
+
throw new RpcError2(NO_DEPLOYMENT_DATA, "Account deployment data is not available");
|
|
21359
|
+
}
|
|
21360
|
+
throw new RpcError2(
|
|
21361
|
+
UNKNOWN_ERROR,
|
|
21362
|
+
err2 instanceof Error ? err2.message : "Could not read deployment data"
|
|
21363
|
+
);
|
|
21237
21364
|
}
|
|
21238
21365
|
case "wallet_supportedSpecs":
|
|
21239
21366
|
return SUPPORTED_SPECS;
|
|
@@ -21550,6 +21677,7 @@ exports.useChipiWalletObject = useChipiWalletObject;
|
|
|
21550
21677
|
exports.useCreateSessionKey = useCreateSessionKey;
|
|
21551
21678
|
exports.useCreateWallet = useCreateWallet;
|
|
21552
21679
|
exports.useExecuteWithSession = useExecuteWithSession;
|
|
21680
|
+
exports.useExternalSignerExecute = useExternalSignerExecute;
|
|
21553
21681
|
exports.useGetSessionData = useGetSessionData;
|
|
21554
21682
|
exports.useGetSku = useGetSku;
|
|
21555
21683
|
exports.useGetSkuList = useGetSkuList;
|