@chipi-stack/backend 14.8.0 → 14.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +201 -15
- package/dist/index.d.ts +201 -15
- package/dist/index.js +168 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +163 -10
- package/dist/index.mjs.map +1 -1
- package/dist/skuPurchases.js +9 -1
- package/dist/skuPurchases.js.map +1 -1
- package/dist/skuPurchases.mjs +10 -2
- package/dist/skuPurchases.mjs.map +1 -1
- package/dist/transactions.js +9 -1
- package/dist/transactions.js.map +1 -1
- package/dist/transactions.mjs +10 -2
- package/dist/transactions.mjs.map +1 -1
- package/dist/wallets.js +9 -1
- package/dist/wallets.js.map +1 -1
- package/dist/wallets.mjs +10 -2
- package/dist/wallets.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -392,6 +392,9 @@ function ed25519PubkeyFelts(publicKey) {
|
|
|
392
392
|
const { low, high } = bytesToLeU256(publicKey);
|
|
393
393
|
return [low, high];
|
|
394
394
|
}
|
|
395
|
+
function ed25519OwnerPubkeyParam(publicKey) {
|
|
396
|
+
return ed25519PubkeyFelts(publicKey).map((f) => "0x" + f.toString(16)).join(",");
|
|
397
|
+
}
|
|
395
398
|
async function buildEd25519Envelope(params) {
|
|
396
399
|
const ownerIndex = params.ownerIndex ?? 0n;
|
|
397
400
|
if (ownerIndex < 0n || ownerIndex >= 0x100000000n) {
|
|
@@ -502,6 +505,14 @@ var init_encryption2 = __esm({
|
|
|
502
505
|
init_encryption();
|
|
503
506
|
}
|
|
504
507
|
});
|
|
508
|
+
|
|
509
|
+
// src/shhh/signers/stark.ts
|
|
510
|
+
var stark_exports = {};
|
|
511
|
+
__export(stark_exports, {
|
|
512
|
+
buildStarkEnvelope: () => buildStarkEnvelope,
|
|
513
|
+
starkOwnerId: () => starkOwnerId,
|
|
514
|
+
starkPubkeyFelts: () => starkPubkeyFelts
|
|
515
|
+
});
|
|
505
516
|
function buildStarkEnvelope(params) {
|
|
506
517
|
const pkHex = "0x" + (typeof params.privateKey === "bigint" ? params.privateKey : BigInt(params.privateKey)).toString(16).padStart(64, "0");
|
|
507
518
|
const sig = starknet.ec.starkCurve.sign("0x" + params.messageHash.toString(16), pkHex);
|
|
@@ -952,7 +963,15 @@ var executePaymasterTransaction = async ({
|
|
|
952
963
|
usePasskey ? "encryptKey is required when using passkey. The passkey authentication should have provided the encryptKey." : "encryptKey is required for transaction execution"
|
|
953
964
|
);
|
|
954
965
|
}
|
|
955
|
-
|
|
966
|
+
let walletType = wallet.walletType ?? "READY";
|
|
967
|
+
if (!wallet.walletType) {
|
|
968
|
+
try {
|
|
969
|
+
const resolveProvider = new starknet.RpcProvider({ nodeUrl: shared.WALLET_RPC_ENDPOINTS.CHIPI });
|
|
970
|
+
const onChainClassHash = await resolveProvider.getClassHashAt(wallet.publicKey, "latest");
|
|
971
|
+
walletType = shared.getWalletTypeFromClassHash(onChainClassHash) ?? "READY";
|
|
972
|
+
} catch {
|
|
973
|
+
}
|
|
974
|
+
}
|
|
956
975
|
if (walletType === "SHHH") {
|
|
957
976
|
const { executeShhhSponsoredRaw: executeShhhSponsoredRaw2 } = await Promise.resolve().then(() => (init_execute_paymaster_raw(), execute_paymaster_raw_exports));
|
|
958
977
|
const shhhSignerKind = (wallet.signerKind ?? "STARK") || "STARK";
|
|
@@ -2528,7 +2547,7 @@ var ChipiSessions = class {
|
|
|
2528
2547
|
* Set a spending policy for a session key + token pair.
|
|
2529
2548
|
*
|
|
2530
2549
|
* This executes a sponsored transaction (using owner signature) to call
|
|
2531
|
-
* `set_spending_policy` on the CHIPI
|
|
2550
|
+
* `set_spending_policy` on the wallet contract (CHIPI v29 or SHHH V8.4).
|
|
2532
2551
|
*
|
|
2533
2552
|
* The contract enforces these limits automatically during `__execute__()` on
|
|
2534
2553
|
* ERC-20 operations (transfer, approve, increase_allowance) made by the session.
|
|
@@ -2556,9 +2575,9 @@ var ChipiSessions = class {
|
|
|
2556
2575
|
async setSpendingPolicy(params, bearerToken) {
|
|
2557
2576
|
const { encryptKey, wallet, spendingPolicyConfig } = params;
|
|
2558
2577
|
const { sessionPublicKey, token, maxPerCall, maxPerWindow, windowSeconds } = spendingPolicyConfig;
|
|
2559
|
-
if (wallet.walletType && wallet.walletType !== "CHIPI") {
|
|
2578
|
+
if (wallet.walletType && wallet.walletType !== "CHIPI" && wallet.walletType !== "SHHH") {
|
|
2560
2579
|
throw new shared.ChipiSessionError(
|
|
2561
|
-
`Spending policies
|
|
2580
|
+
`Spending policies require CHIPI or SHHH wallet type. Got: ${wallet.walletType}`,
|
|
2562
2581
|
shared.SESSION_ERRORS.INVALID_WALLET_TYPE_FOR_SESSION
|
|
2563
2582
|
);
|
|
2564
2583
|
}
|
|
@@ -2617,7 +2636,7 @@ var ChipiSessions = class {
|
|
|
2617
2636
|
const txHash = await executePaymasterTransaction({
|
|
2618
2637
|
params: {
|
|
2619
2638
|
encryptKey,
|
|
2620
|
-
wallet
|
|
2639
|
+
wallet,
|
|
2621
2640
|
calls: [
|
|
2622
2641
|
{
|
|
2623
2642
|
contractAddress: wallet.publicKey,
|
|
@@ -2753,7 +2772,7 @@ var ChipiSessions = class {
|
|
|
2753
2772
|
* Remove a spending policy for a session key + token pair.
|
|
2754
2773
|
*
|
|
2755
2774
|
* This executes a sponsored transaction (using owner signature) to call
|
|
2756
|
-
* `remove_spending_policy` on the CHIPI
|
|
2775
|
+
* `remove_spending_policy` on the wallet contract (CHIPI v29 or SHHH V8.4).
|
|
2757
2776
|
*
|
|
2758
2777
|
* After removal, the session key has no spending limits for this token.
|
|
2759
2778
|
*
|
|
@@ -2773,9 +2792,9 @@ var ChipiSessions = class {
|
|
|
2773
2792
|
*/
|
|
2774
2793
|
async removeSpendingPolicy(params, bearerToken) {
|
|
2775
2794
|
const { encryptKey, wallet, sessionPublicKey, token } = params;
|
|
2776
|
-
if (wallet.walletType && wallet.walletType !== "CHIPI") {
|
|
2795
|
+
if (wallet.walletType && wallet.walletType !== "CHIPI" && wallet.walletType !== "SHHH") {
|
|
2777
2796
|
throw new shared.ChipiSessionError(
|
|
2778
|
-
`Spending policies
|
|
2797
|
+
`Spending policies require CHIPI or SHHH wallet type. Got: ${wallet.walletType}`,
|
|
2779
2798
|
shared.SESSION_ERRORS.INVALID_WALLET_TYPE_FOR_SESSION
|
|
2780
2799
|
);
|
|
2781
2800
|
}
|
|
@@ -2795,7 +2814,7 @@ var ChipiSessions = class {
|
|
|
2795
2814
|
const txHash = await executePaymasterTransaction({
|
|
2796
2815
|
params: {
|
|
2797
2816
|
encryptKey,
|
|
2798
|
-
wallet
|
|
2817
|
+
wallet,
|
|
2799
2818
|
calls: [
|
|
2800
2819
|
{
|
|
2801
2820
|
contractAddress: wallet.publicKey,
|
|
@@ -3165,6 +3184,43 @@ var signTypedData = async ({
|
|
|
3165
3184
|
throw error;
|
|
3166
3185
|
}
|
|
3167
3186
|
};
|
|
3187
|
+
function toFeltHex(x) {
|
|
3188
|
+
return "0x" + x.toString(16).padStart(64, "0");
|
|
3189
|
+
}
|
|
3190
|
+
var signTypedDataArray = async ({
|
|
3191
|
+
params
|
|
3192
|
+
}) => {
|
|
3193
|
+
const { encryptKey, wallet, typedData: typedData2 } = params;
|
|
3194
|
+
if (!encryptKey) throw new Error("encryptKey is required for signing typed data");
|
|
3195
|
+
if (!wallet || !wallet.encryptedPrivateKey || !wallet.publicKey) {
|
|
3196
|
+
throw new Error("wallet with publicKey and encryptedPrivateKey is required");
|
|
3197
|
+
}
|
|
3198
|
+
if (!typedData2) throw new Error("typedData is required for signing");
|
|
3199
|
+
const walletType = wallet.walletType ?? "READY";
|
|
3200
|
+
if (!Object.prototype.hasOwnProperty.call(shared.WALLET_RPC_ENDPOINTS, walletType)) {
|
|
3201
|
+
throw new Error(`Unsupported wallet type: "${String(walletType)}"`);
|
|
3202
|
+
}
|
|
3203
|
+
let privateKeyDecrypted;
|
|
3204
|
+
try {
|
|
3205
|
+
privateKeyDecrypted = exports.decryptPrivateKey(wallet.encryptedPrivateKey, encryptKey);
|
|
3206
|
+
} catch {
|
|
3207
|
+
throw new Error("Failed to decrypt private key. Verify the encryptKey is correct.");
|
|
3208
|
+
}
|
|
3209
|
+
const messageHash = BigInt(starknet.typedData.getMessageHash(typedData2, wallet.publicKey));
|
|
3210
|
+
if (walletType === "SHHH") {
|
|
3211
|
+
const { buildStarkEnvelope: buildStarkEnvelope2 } = await Promise.resolve().then(() => (init_stark(), stark_exports));
|
|
3212
|
+
const envelope = buildStarkEnvelope2({
|
|
3213
|
+
privateKey: privateKeyDecrypted,
|
|
3214
|
+
messageHash,
|
|
3215
|
+
ownerIndex: 0n
|
|
3216
|
+
});
|
|
3217
|
+
return envelope.map(toFeltHex);
|
|
3218
|
+
}
|
|
3219
|
+
const provider = new starknet.RpcProvider({ nodeUrl: shared.WALLET_RPC_ENDPOINTS[walletType] });
|
|
3220
|
+
const account = new starknet.Account({ provider, address: wallet.publicKey, signer: privateKeyDecrypted });
|
|
3221
|
+
const { r, s } = normalizeSignature(await account.signMessage(typedData2));
|
|
3222
|
+
return [r, s];
|
|
3223
|
+
};
|
|
3168
3224
|
|
|
3169
3225
|
// src/chipi-sdk.ts
|
|
3170
3226
|
var ChipiSDK = class {
|
|
@@ -3189,6 +3245,7 @@ var ChipiSDK = class {
|
|
|
3189
3245
|
this.purchaseSku = this.purchaseSku.bind(this);
|
|
3190
3246
|
this.getUsdAmount = this.getUsdAmount.bind(this);
|
|
3191
3247
|
this.signTypedData = this.signTypedData.bind(this);
|
|
3248
|
+
this.signTypedDataArray = this.signTypedDataArray.bind(this);
|
|
3192
3249
|
this.createPaymasterAdapter = this.createPaymasterAdapter.bind(this);
|
|
3193
3250
|
this.createX402Facilitator = this.createX402Facilitator.bind(this);
|
|
3194
3251
|
}
|
|
@@ -3317,6 +3374,14 @@ var ChipiSDK = class {
|
|
|
3317
3374
|
async signTypedData({ params }) {
|
|
3318
3375
|
return signTypedData({ params });
|
|
3319
3376
|
}
|
|
3377
|
+
/**
|
|
3378
|
+
* Sign SNIP-12 typed data and return the full signature span (felt strings) —
|
|
3379
|
+
* the shape a dApp's `wallet_signTypedData` expects. Wallet-type aware:
|
|
3380
|
+
* SHHH returns the V2_SNIP12 owner envelope; standard accounts return [r, s].
|
|
3381
|
+
*/
|
|
3382
|
+
async signTypedDataArray({ params }) {
|
|
3383
|
+
return signTypedDataArray({ params });
|
|
3384
|
+
}
|
|
3320
3385
|
/**
|
|
3321
3386
|
* Transfer tokens
|
|
3322
3387
|
*/
|
|
@@ -3839,6 +3904,12 @@ function eip191PubkeyFelts(pubkey) {
|
|
|
3839
3904
|
function eip191OwnerId(pubkey) {
|
|
3840
3905
|
return ownerCommitment(EIP191_KIND_TAG_FELT, eip191PubkeyFelts(pubkey));
|
|
3841
3906
|
}
|
|
3907
|
+
function eip191OwnerPubkeyParam(pubkey) {
|
|
3908
|
+
assertBytes("secp256k1 x coordinate", pubkey.x, 32);
|
|
3909
|
+
assertBytes("secp256k1 y coordinate", pubkey.y, 32);
|
|
3910
|
+
const toHex = (b) => "0x" + Array.from(b, (v) => v.toString(16).padStart(2, "0")).join("");
|
|
3911
|
+
return `${toHex(pubkey.x)},${toHex(pubkey.y)}`;
|
|
3912
|
+
}
|
|
3842
3913
|
function parseEip191Signature(signatureHex) {
|
|
3843
3914
|
const hex = signatureHex.startsWith("0x") ? signatureHex.slice(2) : signatureHex;
|
|
3844
3915
|
if (hex.length !== 130) {
|
|
@@ -4061,6 +4132,12 @@ function webauthnPubkeyFelts(pub) {
|
|
|
4061
4132
|
function webauthnOwnerId(pub) {
|
|
4062
4133
|
return ownerCommitment(WEBAUTHN_KIND_TAG_FELT, webauthnPubkeyFelts(pub));
|
|
4063
4134
|
}
|
|
4135
|
+
function webauthnOwnerPubkeyParam(pub) {
|
|
4136
|
+
assertBytes2("P-256 x coordinate", pub.x, 32);
|
|
4137
|
+
assertBytes2("P-256 y coordinate", pub.y, 32);
|
|
4138
|
+
const toHex = (b) => "0x" + Array.from(b, (v) => v.toString(16).padStart(2, "0")).join("");
|
|
4139
|
+
return `${toHex(pub.x)},${toHex(pub.y)}`;
|
|
4140
|
+
}
|
|
4064
4141
|
function buildWebAuthnEnvelopeFromAssertion(params) {
|
|
4065
4142
|
const ownerIndex = params.ownerIndex ?? 0n;
|
|
4066
4143
|
if (ownerIndex < 0n || ownerIndex >= 0x100000000n) {
|
|
@@ -4616,6 +4693,82 @@ function secondsUntilExecutable(validAfterSecs, nowSecs) {
|
|
|
4616
4693
|
init_threshold();
|
|
4617
4694
|
init_execute_paymaster_raw();
|
|
4618
4695
|
|
|
4696
|
+
// src/shhh/account.ts
|
|
4697
|
+
init_oe();
|
|
4698
|
+
init_stark();
|
|
4699
|
+
init_execute_paymaster_raw();
|
|
4700
|
+
function generateNonce2() {
|
|
4701
|
+
return BigInt(Date.now()) << 24n | BigInt(Math.floor(Math.random() * 16777216));
|
|
4702
|
+
}
|
|
4703
|
+
var ShhhAccount = class {
|
|
4704
|
+
constructor(provider, address, privateKey, options = {}) {
|
|
4705
|
+
this.provider = provider;
|
|
4706
|
+
this.address = address;
|
|
4707
|
+
this.privateKey = privateKey;
|
|
4708
|
+
this.ownerIndex = options.ownerIndex ?? 0n;
|
|
4709
|
+
this.chainId = options.chainId ?? resolveShhhChainId({});
|
|
4710
|
+
this.submitFn = options.submit;
|
|
4711
|
+
}
|
|
4712
|
+
/**
|
|
4713
|
+
* Build + sign an OutsideExecution for `calls` and return the
|
|
4714
|
+
* serialized `execute_from_outside_v2` calldata (plus the underlying
|
|
4715
|
+
* pieces). Use this when you want to broadcast the calldata yourself.
|
|
4716
|
+
*/
|
|
4717
|
+
async signExecution(calls, options = {}) {
|
|
4718
|
+
if (options.validForSeconds !== void 0) {
|
|
4719
|
+
const maxValid = exports.MAX_OE_VALIDITY_WINDOW_SECONDS - OE_EXECUTE_AFTER_CLOCK_SKEW_BUFFER;
|
|
4720
|
+
if (!Number.isFinite(options.validForSeconds) || options.validForSeconds <= 0) {
|
|
4721
|
+
throw new Error(
|
|
4722
|
+
"ShhhAccount: validForSeconds must be a positive finite number of seconds."
|
|
4723
|
+
);
|
|
4724
|
+
}
|
|
4725
|
+
if (options.validForSeconds > maxValid) {
|
|
4726
|
+
throw new Error(
|
|
4727
|
+
`ShhhAccount: validForSeconds (${options.validForSeconds}) exceeds the max ${maxValid}s (the account caps the OE window at ${exports.MAX_OE_VALIDITY_WINDOW_SECONDS}s and ${OE_EXECUTE_AFTER_CLOCK_SKEW_BUFFER}s is reserved for clock skew).`
|
|
4728
|
+
);
|
|
4729
|
+
}
|
|
4730
|
+
}
|
|
4731
|
+
const outsideExecution = buildOutsideExecution({
|
|
4732
|
+
nonce: options.nonce ?? generateNonce2(),
|
|
4733
|
+
calls,
|
|
4734
|
+
...options.validForSeconds !== void 0 ? { executeBefore: BigInt(Math.floor(Date.now() / 1e3) + options.validForSeconds) } : {}
|
|
4735
|
+
});
|
|
4736
|
+
const messageHash = computeOeHash(outsideExecution, this.address, this.chainId);
|
|
4737
|
+
const signature = buildStarkEnvelope({
|
|
4738
|
+
privateKey: this.privateKey,
|
|
4739
|
+
messageHash,
|
|
4740
|
+
ownerIndex: this.ownerIndex
|
|
4741
|
+
});
|
|
4742
|
+
const calldata = serializeExecuteFromOutsideV2Calldata({ outsideExecution, signature });
|
|
4743
|
+
return { outsideExecution, signature, messageHash, calldata };
|
|
4744
|
+
}
|
|
4745
|
+
/**
|
|
4746
|
+
* Sign `calls` and broadcast them via the configured `submit` strategy.
|
|
4747
|
+
* Mirrors starknet.js `Account.execute` ergonomically. Returns the
|
|
4748
|
+
* transaction hash without waiting for inclusion — use
|
|
4749
|
+
* `provider.waitForTransaction(transactionHash)` if you need to block.
|
|
4750
|
+
*/
|
|
4751
|
+
async execute(calls, options = {}) {
|
|
4752
|
+
if (!this.submitFn) {
|
|
4753
|
+
throw new Error(
|
|
4754
|
+
"ShhhAccount.execute: no submit strategy configured. Pass `submit` in the ShhhAccount constructor options (e.g. submitViaAccount(fundedAccount) for self-sovereign, or a paymaster relay for gasless), or call signExecution() and broadcast the calldata yourself."
|
|
4755
|
+
);
|
|
4756
|
+
}
|
|
4757
|
+
const { calldata } = await this.signExecution(calls, options);
|
|
4758
|
+
return this.submitFn({ accountAddress: this.address, calldata });
|
|
4759
|
+
}
|
|
4760
|
+
};
|
|
4761
|
+
function submitViaAccount(funded) {
|
|
4762
|
+
return async ({ accountAddress, calldata }) => {
|
|
4763
|
+
const { transaction_hash } = await funded.execute({
|
|
4764
|
+
contractAddress: accountAddress,
|
|
4765
|
+
entrypoint: "execute_from_outside_v2",
|
|
4766
|
+
calldata
|
|
4767
|
+
});
|
|
4768
|
+
return { transactionHash: transaction_hash };
|
|
4769
|
+
};
|
|
4770
|
+
}
|
|
4771
|
+
|
|
4619
4772
|
Object.defineProperty(exports, "Chain", {
|
|
4620
4773
|
enumerable: true,
|
|
4621
4774
|
get: function () { return types.Chain; }
|
|
@@ -4648,6 +4801,7 @@ exports.OP_ROTATE_OWNER = OP_ROTATE_OWNER;
|
|
|
4648
4801
|
exports.OP_SET_THRESHOLD = OP_SET_THRESHOLD;
|
|
4649
4802
|
exports.ROLE_GUARDIAN = ROLE_GUARDIAN;
|
|
4650
4803
|
exports.ROLE_OWNER = ROLE_OWNER;
|
|
4804
|
+
exports.ShhhAccount = ShhhAccount;
|
|
4651
4805
|
exports.TIMELOCK_SECONDS = TIMELOCK_SECONDS;
|
|
4652
4806
|
exports.VIEW_SELECTORS = VIEW_SELECTORS;
|
|
4653
4807
|
exports.X402Facilitator = X402Facilitator;
|
|
@@ -4686,9 +4840,11 @@ exports.computeOeHash = computeOeHash;
|
|
|
4686
4840
|
exports.computeShhhAddress = computeShhhAddress;
|
|
4687
4841
|
exports.computeSnip12Hash = computeSnip12Hash;
|
|
4688
4842
|
exports.ed25519OwnerId = ed25519OwnerId;
|
|
4843
|
+
exports.ed25519OwnerPubkeyParam = ed25519OwnerPubkeyParam;
|
|
4689
4844
|
exports.ed25519PubkeyFelts = ed25519PubkeyFelts;
|
|
4690
4845
|
exports.ed25519SignedBytes = ed25519SignedBytes;
|
|
4691
4846
|
exports.eip191OwnerId = eip191OwnerId;
|
|
4847
|
+
exports.eip191OwnerPubkeyParam = eip191OwnerPubkeyParam;
|
|
4692
4848
|
exports.eip191PubkeyFelts = eip191PubkeyFelts;
|
|
4693
4849
|
exports.estimateThresholdGasOverhead = estimateThresholdGasOverhead;
|
|
4694
4850
|
exports.executeShhhSponsoredRaw = executeShhhSponsoredRaw;
|
|
@@ -4714,10 +4870,13 @@ exports.secondsUntilExecutable = secondsUntilExecutable;
|
|
|
4714
4870
|
exports.serializeExecuteFromOutsideV2Calldata = serializeExecuteFromOutsideV2Calldata;
|
|
4715
4871
|
exports.signBootstrapMessage = signBootstrapMessage;
|
|
4716
4872
|
exports.signTypedData = signTypedData;
|
|
4873
|
+
exports.signTypedDataArray = signTypedDataArray;
|
|
4717
4874
|
exports.snip12HashToHexAsciiBytes = snip12HashToHexAsciiBytes;
|
|
4718
4875
|
exports.starkOwnerId = starkOwnerId;
|
|
4719
4876
|
exports.starkPubkeyFelts = starkPubkeyFelts;
|
|
4877
|
+
exports.submitViaAccount = submitViaAccount;
|
|
4720
4878
|
exports.webauthnOwnerId = webauthnOwnerId;
|
|
4879
|
+
exports.webauthnOwnerPubkeyParam = webauthnOwnerPubkeyParam;
|
|
4721
4880
|
exports.webauthnPubkeyFelts = webauthnPubkeyFelts;
|
|
4722
4881
|
exports.wrapV2Snip12Envelope = wrapV2Snip12Envelope;
|
|
4723
4882
|
exports.wrapV2ThresholdEnvelope = wrapV2ThresholdEnvelope;
|