@chipi-stack/backend 11.21.0 → 12.0.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/{client-E8WQVssY.d.mts → client-43S3tkH3.d.mts} +6 -0
- package/dist/{client-E8WQVssY.d.ts → client-43S3tkH3.d.ts} +6 -0
- package/dist/index.d.mts +204 -6
- package/dist/index.d.ts +204 -6
- package/dist/index.js +645 -76
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +647 -79
- package/dist/index.mjs.map +1 -1
- package/dist/skuTransactions.d.mts +1 -1
- package/dist/skuTransactions.d.ts +1 -1
- package/dist/skuTransactions.js +38 -58
- package/dist/skuTransactions.js.map +1 -1
- package/dist/skuTransactions.mjs +39 -59
- package/dist/skuTransactions.mjs.map +1 -1
- package/dist/skus.d.mts +1 -1
- package/dist/skus.d.ts +1 -1
- package/dist/transactions.d.mts +1 -1
- package/dist/transactions.d.ts +1 -1
- package/dist/transactions.js +33 -53
- package/dist/transactions.js.map +1 -1
- package/dist/transactions.mjs +34 -54
- package/dist/transactions.mjs.map +1 -1
- package/dist/wallets.d.mts +8 -4
- package/dist/wallets.d.ts +8 -4
- package/dist/wallets.js +43 -15
- package/dist/wallets.js.map +1 -1
- package/dist/wallets.mjs +45 -17
- package/dist/wallets.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -19,6 +19,7 @@ var ChipiClient = class {
|
|
|
19
19
|
this.customAlphaUrl = config.alphaUrl;
|
|
20
20
|
this.baseUrl = this.getBaseUrl();
|
|
21
21
|
this.nodeUrl = config.nodeUrl || shared.STARKNET_NETWORKS.MAINNET;
|
|
22
|
+
this.sdkVersion = "11.21.0";
|
|
22
23
|
}
|
|
23
24
|
/**
|
|
24
25
|
* Get the API public key (for internal SDK use)
|
|
@@ -27,10 +28,19 @@ var ChipiClient = class {
|
|
|
27
28
|
return this.apiPublicKey;
|
|
28
29
|
}
|
|
29
30
|
getBaseUrl() {
|
|
31
|
+
const version = `v${shared.API_VERSIONING.VERSION}`;
|
|
30
32
|
if (this.customAlphaUrl) {
|
|
31
|
-
|
|
33
|
+
const cleanUrl = this.customAlphaUrl.replace(/\/v\d+$/, "").replace(/\/$/, "");
|
|
34
|
+
return `${cleanUrl}/${version}`;
|
|
32
35
|
}
|
|
33
|
-
return
|
|
36
|
+
return `https://celebrated-vision-production-66a5.up.railway.app/${version}`;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Add API version query parameters to track the API version being used
|
|
40
|
+
* This helps the backend handle versioning and track which SDK versions are in use
|
|
41
|
+
*/
|
|
42
|
+
addVersionParams(url) {
|
|
43
|
+
url.searchParams.append("__chipi_api_version", shared.API_VERSIONING.VERSION_DATE);
|
|
34
44
|
}
|
|
35
45
|
getHeaders(bearerToken) {
|
|
36
46
|
const headers = {
|
|
@@ -49,6 +59,7 @@ var ChipiClient = class {
|
|
|
49
59
|
}) {
|
|
50
60
|
try {
|
|
51
61
|
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
62
|
+
this.addVersionParams(url);
|
|
52
63
|
if (params) {
|
|
53
64
|
Object.entries(params).forEach(([key, value]) => {
|
|
54
65
|
if (value !== void 0 && value !== null) {
|
|
@@ -80,14 +91,16 @@ var ChipiClient = class {
|
|
|
80
91
|
body
|
|
81
92
|
}) {
|
|
82
93
|
try {
|
|
83
|
-
const
|
|
94
|
+
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
95
|
+
this.addVersionParams(url);
|
|
96
|
+
const response = await fetch(url.toString(), {
|
|
84
97
|
method: "POST",
|
|
85
98
|
headers: this.getHeaders(bearerToken),
|
|
86
99
|
body: body ? JSON.stringify(body) : void 0
|
|
87
100
|
});
|
|
88
101
|
const data = await response.json();
|
|
89
102
|
if (!response.ok) {
|
|
90
|
-
console.
|
|
103
|
+
console.error("there was an error", data);
|
|
91
104
|
const errorData = shared.validateErrorResponse(data);
|
|
92
105
|
throw new shared.ChipiApiError(
|
|
93
106
|
errorData.message,
|
|
@@ -106,7 +119,9 @@ var ChipiClient = class {
|
|
|
106
119
|
body
|
|
107
120
|
}) {
|
|
108
121
|
try {
|
|
109
|
-
const
|
|
122
|
+
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
123
|
+
this.addVersionParams(url);
|
|
124
|
+
const response = await fetch(url.toString(), {
|
|
110
125
|
method: "PUT",
|
|
111
126
|
headers: this.getHeaders(bearerToken),
|
|
112
127
|
body: body ? JSON.stringify(body) : void 0
|
|
@@ -130,7 +145,9 @@ var ChipiClient = class {
|
|
|
130
145
|
bearerToken
|
|
131
146
|
}) {
|
|
132
147
|
try {
|
|
133
|
-
const
|
|
148
|
+
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
149
|
+
this.addVersionParams(url);
|
|
150
|
+
const response = await fetch(url.toString(), {
|
|
134
151
|
method: "DELETE",
|
|
135
152
|
headers: this.getHeaders(bearerToken)
|
|
136
153
|
});
|
|
@@ -181,23 +198,27 @@ var ChipiWallets = class {
|
|
|
181
198
|
}
|
|
182
199
|
async createWallet(params) {
|
|
183
200
|
try {
|
|
184
|
-
const {
|
|
185
|
-
|
|
201
|
+
const {
|
|
202
|
+
encryptKey,
|
|
203
|
+
externalUserId,
|
|
204
|
+
bearerToken,
|
|
205
|
+
userId,
|
|
206
|
+
walletType = "CHIPI"
|
|
207
|
+
// Default to CHIPI wallet
|
|
208
|
+
} = params;
|
|
209
|
+
const rpcUrl = walletType === "READY" ? shared.WALLET_RPC_ENDPOINTS.READY : shared.WALLET_RPC_ENDPOINTS.CHIPI;
|
|
210
|
+
const provider = new starknet.RpcProvider({ nodeUrl: rpcUrl });
|
|
186
211
|
const privateKeyAX = this.getPrivateKeyAX();
|
|
187
212
|
const starkKeyPubAX = starknet.ec.starkCurve.getStarkKey(privateKeyAX);
|
|
188
|
-
const accountClassHash = "
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const AXConstructorCallData = starknet.CallData.compile({
|
|
194
|
-
owner: axSigner,
|
|
195
|
-
guardian: axGuardian
|
|
196
|
-
});
|
|
213
|
+
const accountClassHash = walletType === "READY" ? shared.WALLET_CLASS_HASHES.READY : shared.WALLET_CLASS_HASHES.CHIPI;
|
|
214
|
+
const constructorCallData = this.buildConstructorCallData(
|
|
215
|
+
walletType,
|
|
216
|
+
starkKeyPubAX
|
|
217
|
+
);
|
|
197
218
|
const publicKey = starknet.hash.calculateContractAddressFromHash(
|
|
198
219
|
starkKeyPubAX,
|
|
199
220
|
accountClassHash,
|
|
200
|
-
|
|
221
|
+
constructorCallData,
|
|
201
222
|
0
|
|
202
223
|
);
|
|
203
224
|
const account = new starknet.Account(provider, publicKey, privateKeyAX);
|
|
@@ -205,7 +226,10 @@ var ChipiWallets = class {
|
|
|
205
226
|
endpoint: `${shared.API_ENDPOINTS.CHIPI_WALLETS}/prepare-creation`,
|
|
206
227
|
bearerToken,
|
|
207
228
|
body: {
|
|
208
|
-
publicKey
|
|
229
|
+
publicKey,
|
|
230
|
+
walletType,
|
|
231
|
+
starkKeyPubAX
|
|
232
|
+
// Needed for backend to build deployment data
|
|
209
233
|
}
|
|
210
234
|
});
|
|
211
235
|
const { typeData, accountClassHash: accountClassHashResponse } = typeDataResponse;
|
|
@@ -214,7 +238,7 @@ var ChipiWallets = class {
|
|
|
214
238
|
class_hash: accountClassHashResponse,
|
|
215
239
|
salt: starkKeyPubAX,
|
|
216
240
|
unique: `${starknet.num.toHex(0)}`,
|
|
217
|
-
calldata:
|
|
241
|
+
calldata: constructorCallData.map((value) => starknet.num.toHex(value))
|
|
218
242
|
};
|
|
219
243
|
const encryptedPrivateKey = encryptPrivateKey(privateKeyAX, encryptKey);
|
|
220
244
|
const executeTransactionResponse = await this.client.post({
|
|
@@ -224,6 +248,7 @@ var ChipiWallets = class {
|
|
|
224
248
|
externalUserId,
|
|
225
249
|
userId,
|
|
226
250
|
publicKey,
|
|
251
|
+
walletType,
|
|
227
252
|
userSignature: {
|
|
228
253
|
r: userSignature.r.toString(),
|
|
229
254
|
s: userSignature.s.toString(),
|
|
@@ -244,7 +269,7 @@ var ChipiWallets = class {
|
|
|
244
269
|
wallet: executeTransactionResponse.wallet
|
|
245
270
|
};
|
|
246
271
|
} catch (error) {
|
|
247
|
-
console.error("
|
|
272
|
+
console.error("Detailed error:", error);
|
|
248
273
|
if (error instanceof Error && error.message.includes("SSL")) {
|
|
249
274
|
throw new Error(
|
|
250
275
|
"SSL connection error. Try using NODE_TLS_REJECT_UNAUTHORIZED=0 or verify the RPC URL"
|
|
@@ -256,6 +281,26 @@ var ChipiWallets = class {
|
|
|
256
281
|
);
|
|
257
282
|
}
|
|
258
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* Build constructor calldata based on wallet type
|
|
286
|
+
* - CHIPI: Simple OpenZeppelin account with just public_key
|
|
287
|
+
* - ARGENT: Argent X Account with owner/guardian structure
|
|
288
|
+
*/
|
|
289
|
+
buildConstructorCallData(walletType, starkKeyPubAX) {
|
|
290
|
+
if (walletType === "READY") {
|
|
291
|
+
const axSigner = new starknet.CairoCustomEnum({
|
|
292
|
+
Starknet: { pubkey: starkKeyPubAX }
|
|
293
|
+
});
|
|
294
|
+
const axGuardian = new starknet.CairoOption(starknet.CairoOptionVariant.None);
|
|
295
|
+
return starknet.CallData.compile({
|
|
296
|
+
owner: axSigner,
|
|
297
|
+
guardian: axGuardian
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
return starknet.CallData.compile({
|
|
301
|
+
public_key: starkKeyPubAX
|
|
302
|
+
});
|
|
303
|
+
}
|
|
259
304
|
/**
|
|
260
305
|
* Create a custodial merchant wallet
|
|
261
306
|
*/
|
|
@@ -301,11 +346,18 @@ var ChipiWallets = class {
|
|
|
301
346
|
var executePaymasterTransaction = async ({
|
|
302
347
|
params,
|
|
303
348
|
bearerToken,
|
|
304
|
-
|
|
305
|
-
backendUrl
|
|
349
|
+
client
|
|
306
350
|
}) => {
|
|
307
351
|
try {
|
|
308
352
|
const { encryptKey, wallet, calls, saveToDatabase } = params;
|
|
353
|
+
if (!wallet.walletType) {
|
|
354
|
+
console.warn(
|
|
355
|
+
`[ChipiSDK] Wallet ${wallet.publicKey.slice(0, 10)}... has no walletType - defaulting to ARGENT for backward compatibility`
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
const walletType = wallet.walletType ?? "READY";
|
|
359
|
+
const rpcUrl = walletType === "READY" ? shared.WALLET_RPC_ENDPOINTS.READY : shared.WALLET_RPC_ENDPOINTS.CHIPI;
|
|
360
|
+
const accountClassHash = walletType === "READY" ? shared.WALLET_CLASS_HASHES.READY : shared.WALLET_CLASS_HASHES.CHIPI;
|
|
309
361
|
const privateKeyDecrypted = decryptPrivateKey(
|
|
310
362
|
wallet.encryptedPrivateKey,
|
|
311
363
|
encryptKey
|
|
@@ -313,68 +365,164 @@ var executePaymasterTransaction = async ({
|
|
|
313
365
|
if (!privateKeyDecrypted) {
|
|
314
366
|
throw new Error("Failed to decrypt private key");
|
|
315
367
|
}
|
|
316
|
-
const provider = new starknet.RpcProvider({
|
|
317
|
-
nodeUrl: "https://cloud.argent-api.com/v1/starknet/mainnet/rpc/v0.7"
|
|
318
|
-
});
|
|
368
|
+
const provider = new starknet.RpcProvider({ nodeUrl: rpcUrl });
|
|
319
369
|
const account = new starknet.Account(
|
|
320
370
|
provider,
|
|
321
371
|
wallet.publicKey,
|
|
322
372
|
privateKeyDecrypted
|
|
323
373
|
);
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
374
|
+
const typeData = await client.post({
|
|
375
|
+
endpoint: "/transactions/prepare-typed-data",
|
|
376
|
+
bearerToken,
|
|
377
|
+
body: {
|
|
378
|
+
publicKey: wallet.publicKey,
|
|
379
|
+
walletType,
|
|
380
|
+
calls,
|
|
381
|
+
accountClassHash
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
const userSignature = await account.signMessage(typeData);
|
|
385
|
+
const result = await client.post({
|
|
386
|
+
endpoint: "/transactions/execute-sponsored-transaction",
|
|
387
|
+
bearerToken,
|
|
388
|
+
body: {
|
|
389
|
+
publicKey: wallet.publicKey,
|
|
390
|
+
typeData,
|
|
391
|
+
userSignature: {
|
|
392
|
+
r: userSignature.r.toString(),
|
|
393
|
+
s: userSignature.s.toString(),
|
|
394
|
+
recovery: userSignature.recovery
|
|
332
395
|
},
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
calls,
|
|
336
|
-
accountClassHash: "0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f"
|
|
337
|
-
})
|
|
396
|
+
saveToDatabase,
|
|
397
|
+
walletType
|
|
338
398
|
}
|
|
339
|
-
);
|
|
340
|
-
if (!
|
|
341
|
-
|
|
342
|
-
throw new Error(`Error in API: ${errorText}`);
|
|
399
|
+
});
|
|
400
|
+
if (!result.transactionHash) {
|
|
401
|
+
throw new Error("The response does not contain the transaction hash");
|
|
343
402
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
403
|
+
return result.transactionHash;
|
|
404
|
+
} catch (error) {
|
|
405
|
+
console.error("Error sending transaction with paymaster", error);
|
|
406
|
+
throw error;
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
var executePaymasterTransactionWithSession = async ({
|
|
410
|
+
params,
|
|
411
|
+
bearerToken,
|
|
412
|
+
client
|
|
413
|
+
}) => {
|
|
414
|
+
const { encryptKey, wallet, session, calls, saveToDatabase } = params;
|
|
415
|
+
if (wallet.walletType !== "CHIPI") {
|
|
416
|
+
console.error(
|
|
417
|
+
"[ChipiSDK:Session:Execute] Invalid wallet type for session execution",
|
|
348
418
|
{
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
},
|
|
355
|
-
body: JSON.stringify({
|
|
356
|
-
publicKey: wallet.publicKey,
|
|
357
|
-
typeData,
|
|
358
|
-
userSignature: {
|
|
359
|
-
r: userSignature.r.toString(),
|
|
360
|
-
s: userSignature.s.toString(),
|
|
361
|
-
recovery: userSignature.recovery
|
|
362
|
-
},
|
|
363
|
-
saveToDatabase
|
|
364
|
-
})
|
|
419
|
+
provided: wallet.walletType,
|
|
420
|
+
required: "CHIPI",
|
|
421
|
+
expectedClassHash: shared.WALLET_CLASS_HASHES.CHIPI,
|
|
422
|
+
walletAddress: wallet.publicKey?.slice(0, 15) + "...",
|
|
423
|
+
hint: "Session keys only work with CHIPI wallets (SNIP-9 compatible)"
|
|
365
424
|
}
|
|
366
425
|
);
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
426
|
+
throw new shared.ChipiSessionError(
|
|
427
|
+
`Session execution requires CHIPI wallet type. Got: "${wallet.walletType || "undefined"}"`,
|
|
428
|
+
shared.SESSION_ERRORS.INVALID_WALLET_TYPE_FOR_SESSION
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
432
|
+
if (session.validUntil < nowSeconds) {
|
|
433
|
+
console.error("[ChipiSDK:Session:Execute] Session has expired", {
|
|
434
|
+
sessionExpiry: new Date(session.validUntil * 1e3).toISOString(),
|
|
435
|
+
currentTime: new Date(nowSeconds * 1e3).toISOString(),
|
|
436
|
+
expiredAgo: `${nowSeconds - session.validUntil} seconds`
|
|
437
|
+
});
|
|
438
|
+
throw new shared.ChipiSessionError(
|
|
439
|
+
`Session expired at ${new Date(session.validUntil * 1e3).toISOString()}. Create a new session key.`,
|
|
440
|
+
shared.SESSION_ERRORS.SESSION_EXPIRED
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
try {
|
|
444
|
+
const sessionPrivateKey = decryptPrivateKey(
|
|
445
|
+
session.encryptedPrivateKey,
|
|
446
|
+
encryptKey
|
|
447
|
+
);
|
|
448
|
+
if (!sessionPrivateKey) {
|
|
449
|
+
console.error(
|
|
450
|
+
"[ChipiSDK:Session:Execute] Failed to decrypt session private key",
|
|
451
|
+
{
|
|
452
|
+
sessionPubKey: session.publicKey?.slice(0, 15) + "...",
|
|
453
|
+
hint: "Ensure the encryptKey matches the one used when creating the session"
|
|
454
|
+
}
|
|
455
|
+
);
|
|
456
|
+
throw new shared.ChipiSessionError(
|
|
457
|
+
"Failed to decrypt session private key. Verify the encryptKey is correct.",
|
|
458
|
+
shared.SESSION_ERRORS.SESSION_DECRYPTION_FAILED
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
const derivedPubKey = starknet.ec.starkCurve.getStarkKey(sessionPrivateKey);
|
|
462
|
+
if (derivedPubKey.toLowerCase() !== session.publicKey.toLowerCase()) {
|
|
463
|
+
console.error("[ChipiSDK:Session:Execute] Session key mismatch", {
|
|
464
|
+
expected: session.publicKey.slice(0, 15) + "...",
|
|
465
|
+
derived: derivedPubKey.slice(0, 15) + "...",
|
|
466
|
+
hint: "The encrypted private key does not match the stored public key"
|
|
467
|
+
});
|
|
468
|
+
throw new shared.ChipiSessionError(
|
|
469
|
+
"Session key mismatch: decrypted private key does not match the public key",
|
|
470
|
+
shared.SESSION_ERRORS.SESSION_DECRYPTION_FAILED
|
|
471
|
+
);
|
|
370
472
|
}
|
|
371
|
-
const
|
|
473
|
+
const accountClassHash = shared.WALLET_CLASS_HASHES.CHIPI;
|
|
474
|
+
const typeDataResult = await client.post({
|
|
475
|
+
endpoint: "/transactions/prepare-typed-data",
|
|
476
|
+
bearerToken,
|
|
477
|
+
body: {
|
|
478
|
+
publicKey: wallet.publicKey,
|
|
479
|
+
calls,
|
|
480
|
+
accountClassHash,
|
|
481
|
+
walletType: "CHIPI"
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
const msgHash = starknet.typedData.getMessageHash(typeDataResult, wallet.publicKey);
|
|
485
|
+
const { r, s } = starknet.ec.starkCurve.sign(msgHash, sessionPrivateKey);
|
|
486
|
+
const sessionSignature = [
|
|
487
|
+
session.publicKey,
|
|
488
|
+
starknet.num.toHex(r),
|
|
489
|
+
starknet.num.toHex(s),
|
|
490
|
+
starknet.num.toHex(session.validUntil)
|
|
491
|
+
];
|
|
492
|
+
const result = await client.post({
|
|
493
|
+
endpoint: "/transactions/execute-sponsored-transaction",
|
|
494
|
+
bearerToken,
|
|
495
|
+
body: {
|
|
496
|
+
publicKey: wallet.publicKey,
|
|
497
|
+
typeData: typeDataResult,
|
|
498
|
+
// Session signature format - array of 4 hex strings
|
|
499
|
+
userSignature: sessionSignature,
|
|
500
|
+
saveToDatabase,
|
|
501
|
+
walletType: "CHIPI",
|
|
502
|
+
isSessionSignature: true
|
|
503
|
+
// Flag to indicate session signature format
|
|
504
|
+
}
|
|
505
|
+
});
|
|
372
506
|
if (!result.transactionHash) {
|
|
373
|
-
|
|
507
|
+
console.error(
|
|
508
|
+
"[ChipiSDK:Session:Execute] No transaction hash in response",
|
|
509
|
+
{
|
|
510
|
+
result
|
|
511
|
+
}
|
|
512
|
+
);
|
|
513
|
+
throw new Error("Response does not contain transaction hash");
|
|
374
514
|
}
|
|
375
515
|
return result.transactionHash;
|
|
376
516
|
} catch (error) {
|
|
377
|
-
|
|
517
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
518
|
+
if (error instanceof shared.ChipiSessionError) {
|
|
519
|
+
throw error;
|
|
520
|
+
}
|
|
521
|
+
console.error("[ChipiSDK:Session:Execute] Unexpected error", {
|
|
522
|
+
error: err.message,
|
|
523
|
+
walletAddress: wallet.publicKey?.slice(0, 15) + "...",
|
|
524
|
+
sessionPubKey: session.publicKey?.slice(0, 15) + "..."
|
|
525
|
+
});
|
|
378
526
|
throw error;
|
|
379
527
|
}
|
|
380
528
|
};
|
|
@@ -400,8 +548,7 @@ var ChipiTransactions = class {
|
|
|
400
548
|
saveToDatabase
|
|
401
549
|
},
|
|
402
550
|
bearerToken,
|
|
403
|
-
|
|
404
|
-
apiPublicKey: this.client.getApiPublicKey()
|
|
551
|
+
client: this.client
|
|
405
552
|
});
|
|
406
553
|
}
|
|
407
554
|
/**
|
|
@@ -534,16 +681,16 @@ var ChipiSkuTransactions = class {
|
|
|
534
681
|
},
|
|
535
682
|
{
|
|
536
683
|
contractAddress: shared.SKU_CONTRACTS.RECHARGER_WITH_STRK_MAINNET,
|
|
537
|
-
entrypoint: "
|
|
684
|
+
entrypoint: "process_recharge",
|
|
538
685
|
calldata: starknet.CallData.compile({
|
|
539
|
-
|
|
686
|
+
token: tokenAddress,
|
|
540
687
|
amount: starknet.cairo.uint256(parsedAmount),
|
|
541
|
-
|
|
688
|
+
recharge_id: CryptoES__default.default.SHA256(
|
|
542
689
|
CryptoES__default.default.lib.WordArray.random(32)
|
|
543
690
|
// 32 bytes = 256 bits entropy
|
|
544
691
|
).toString().slice(0, 20),
|
|
545
|
-
|
|
546
|
-
|
|
692
|
+
product_code: skuId,
|
|
693
|
+
merchant_slug: shared.CARRIER_IDS.CHIPI_PAY
|
|
547
694
|
})
|
|
548
695
|
},
|
|
549
696
|
{
|
|
@@ -670,6 +817,382 @@ var Users = class {
|
|
|
670
817
|
});
|
|
671
818
|
}
|
|
672
819
|
};
|
|
820
|
+
var ChipiSessions = class {
|
|
821
|
+
constructor(client) {
|
|
822
|
+
this.client = client;
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Validate that the wallet is a CHIPI wallet (required for session operations).
|
|
826
|
+
* Throws ChipiSessionError if wallet type is not CHIPI.
|
|
827
|
+
*/
|
|
828
|
+
validateChipiWallet(walletType, operation, walletPublicKey) {
|
|
829
|
+
if (walletType !== "CHIPI") {
|
|
830
|
+
console.error(`[ChipiSDK:Session:${operation}] Invalid wallet type`, {
|
|
831
|
+
provided: walletType,
|
|
832
|
+
required: "CHIPI",
|
|
833
|
+
expectedClassHash: shared.WALLET_CLASS_HASHES["CHIPI"],
|
|
834
|
+
walletAddress: walletPublicKey ? walletPublicKey.slice(0, 15) + "..." : "(not provided)",
|
|
835
|
+
hint: "Session keys only work with CHIPI wallets (SNIP-9 compatible)"
|
|
836
|
+
});
|
|
837
|
+
throw new shared.ChipiSessionError(
|
|
838
|
+
`Session keys require CHIPI wallet type. Got: "${walletType || "undefined"}". Session keys are only supported for CHIPI wallets with class hash ${shared.WALLET_CLASS_HASHES["CHIPI"]}`,
|
|
839
|
+
shared.SESSION_ERRORS.INVALID_WALLET_TYPE_FOR_SESSION
|
|
840
|
+
);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
/**
|
|
844
|
+
* Convert a Uint8Array to hex string with 0x prefix.
|
|
845
|
+
*/
|
|
846
|
+
toHex(uint8) {
|
|
847
|
+
return "0x" + Array.from(uint8).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Generate a new session keypair locally.
|
|
851
|
+
*
|
|
852
|
+
* This method generates the session keys but does NOT register them on-chain.
|
|
853
|
+
* The returned SessionKeyData should be stored by the developer externally
|
|
854
|
+
* (e.g., in Clerk metadata, database, etc.) - the SDK does NOT persist this.
|
|
855
|
+
*
|
|
856
|
+
* After generating, call `addSessionKeyToContract()` to register the session on-chain.
|
|
857
|
+
*
|
|
858
|
+
* @param params - Session creation parameters
|
|
859
|
+
* @returns SessionKeyData for external storage
|
|
860
|
+
*
|
|
861
|
+
* @example
|
|
862
|
+
* ```typescript
|
|
863
|
+
* const session = sdk.sessions.createSessionKey({
|
|
864
|
+
* encryptKey: userEncryptKey,
|
|
865
|
+
* durationSeconds: 21600 // 6 hours
|
|
866
|
+
* });
|
|
867
|
+
* // Store session externally (e.g., in Clerk metadata)
|
|
868
|
+
* await saveToClerk(session);
|
|
869
|
+
* ```
|
|
870
|
+
*/
|
|
871
|
+
createSessionKey(params) {
|
|
872
|
+
const { encryptKey, durationSeconds = shared.SESSION_DEFAULTS.DURATION_SECONDS } = params;
|
|
873
|
+
try {
|
|
874
|
+
const rawPrivateKey = starknet.ec.starkCurve.utils.randomPrivateKey();
|
|
875
|
+
const privateKeyHex = this.toHex(rawPrivateKey);
|
|
876
|
+
const publicKey = starknet.ec.starkCurve.getStarkKey(privateKeyHex);
|
|
877
|
+
const validUntil = Math.floor(Date.now() / 1e3) + durationSeconds;
|
|
878
|
+
const encryptedPrivateKey = encryptPrivateKey(privateKeyHex, encryptKey);
|
|
879
|
+
return {
|
|
880
|
+
publicKey,
|
|
881
|
+
encryptedPrivateKey,
|
|
882
|
+
validUntil
|
|
883
|
+
};
|
|
884
|
+
} catch (error) {
|
|
885
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
886
|
+
console.error(
|
|
887
|
+
"[ChipiSDK:Session:Create] Failed to generate session key",
|
|
888
|
+
{
|
|
889
|
+
error: err.message,
|
|
890
|
+
durationRequested: durationSeconds
|
|
891
|
+
}
|
|
892
|
+
);
|
|
893
|
+
throw new shared.ChipiSessionError(
|
|
894
|
+
`Failed to create session key: ${err.message}`,
|
|
895
|
+
shared.SESSION_ERRORS.SESSION_CREATION_FAILED
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Register a session key on the smart contract.
|
|
901
|
+
*
|
|
902
|
+
* This executes a sponsored transaction (using owner signature) to call
|
|
903
|
+
* `add_or_update_session_key` on the CHIPI wallet contract.
|
|
904
|
+
*
|
|
905
|
+
* The session must be registered before it can be used for transactions.
|
|
906
|
+
*
|
|
907
|
+
* @param params - Session registration parameters
|
|
908
|
+
* @param bearerToken - Authentication token
|
|
909
|
+
* @returns Transaction hash
|
|
910
|
+
*
|
|
911
|
+
* @example
|
|
912
|
+
* ```typescript
|
|
913
|
+
* const txHash = await sdk.sessions.addSessionKeyToContract({
|
|
914
|
+
* encryptKey: userEncryptKey,
|
|
915
|
+
* wallet: userWallet,
|
|
916
|
+
* sessionConfig: {
|
|
917
|
+
* sessionPublicKey: session.publicKey,
|
|
918
|
+
* validUntil: session.validUntil,
|
|
919
|
+
* maxCalls: 1000,
|
|
920
|
+
* allowedEntrypoints: [] // empty = all allowed
|
|
921
|
+
* }
|
|
922
|
+
* }, bearerToken);
|
|
923
|
+
* ```
|
|
924
|
+
*/
|
|
925
|
+
async addSessionKeyToContract(params, bearerToken) {
|
|
926
|
+
const { encryptKey, wallet, sessionConfig } = params;
|
|
927
|
+
this.validateChipiWallet(
|
|
928
|
+
wallet.walletType,
|
|
929
|
+
"AddToContract",
|
|
930
|
+
wallet.publicKey
|
|
931
|
+
);
|
|
932
|
+
try {
|
|
933
|
+
console.log(
|
|
934
|
+
"[ChipiSDK:Session:AddToContract] Registering session on-chain",
|
|
935
|
+
{
|
|
936
|
+
walletAddress: wallet.publicKey.slice(0, 15) + "...",
|
|
937
|
+
sessionPubKey: sessionConfig.sessionPublicKey.slice(0, 15) + "...",
|
|
938
|
+
validUntil: new Date(sessionConfig.validUntil * 1e3).toISOString(),
|
|
939
|
+
maxCalls: sessionConfig.maxCalls,
|
|
940
|
+
allowedEntrypoints: sessionConfig.allowedEntrypoints.length
|
|
941
|
+
}
|
|
942
|
+
);
|
|
943
|
+
const calldata = [
|
|
944
|
+
sessionConfig.sessionPublicKey,
|
|
945
|
+
starknet.num.toHex(sessionConfig.validUntil),
|
|
946
|
+
starknet.num.toHex(sessionConfig.maxCalls),
|
|
947
|
+
// Array: first element is length, then elements
|
|
948
|
+
starknet.num.toHex(sessionConfig.allowedEntrypoints.length),
|
|
949
|
+
...sessionConfig.allowedEntrypoints
|
|
950
|
+
];
|
|
951
|
+
const txHash = await executePaymasterTransaction({
|
|
952
|
+
params: {
|
|
953
|
+
encryptKey,
|
|
954
|
+
wallet: { ...wallet, walletType: "CHIPI" },
|
|
955
|
+
calls: [
|
|
956
|
+
{
|
|
957
|
+
contractAddress: wallet.publicKey,
|
|
958
|
+
entrypoint: shared.SESSION_ENTRYPOINTS.ADD_OR_UPDATE,
|
|
959
|
+
calldata
|
|
960
|
+
}
|
|
961
|
+
],
|
|
962
|
+
saveToDatabase: false
|
|
963
|
+
// Don't record session management txs
|
|
964
|
+
},
|
|
965
|
+
bearerToken,
|
|
966
|
+
client: this.client
|
|
967
|
+
});
|
|
968
|
+
console.log(
|
|
969
|
+
"[ChipiSDK:Session:AddToContract] Session registered successfully",
|
|
970
|
+
{
|
|
971
|
+
txHash,
|
|
972
|
+
sessionPubKey: sessionConfig.sessionPublicKey.slice(0, 15) + "..."
|
|
973
|
+
}
|
|
974
|
+
);
|
|
975
|
+
return txHash;
|
|
976
|
+
} catch (error) {
|
|
977
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
978
|
+
console.error("[ChipiSDK:Session:AddToContract] Registration failed", {
|
|
979
|
+
error: err.message,
|
|
980
|
+
walletAddress: wallet.publicKey?.slice(0, 15) + "...",
|
|
981
|
+
sessionPubKey: sessionConfig.sessionPublicKey?.slice(0, 15) + "...",
|
|
982
|
+
validUntil: new Date(sessionConfig.validUntil * 1e3).toISOString(),
|
|
983
|
+
maxCalls: sessionConfig.maxCalls
|
|
984
|
+
});
|
|
985
|
+
throw error;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Revoke a session key from the smart contract.
|
|
990
|
+
*
|
|
991
|
+
* This executes a sponsored transaction (using owner signature) to call
|
|
992
|
+
* `revoke_session_key` on the CHIPI wallet contract.
|
|
993
|
+
*
|
|
994
|
+
* After revocation, the session key can no longer be used for transactions.
|
|
995
|
+
*
|
|
996
|
+
* @param params - Session revocation parameters
|
|
997
|
+
* @param bearerToken - Authentication token
|
|
998
|
+
* @returns Transaction hash
|
|
999
|
+
*
|
|
1000
|
+
* @example
|
|
1001
|
+
* ```typescript
|
|
1002
|
+
* const txHash = await sdk.sessions.revokeSessionKey({
|
|
1003
|
+
* encryptKey: userEncryptKey,
|
|
1004
|
+
* wallet: userWallet,
|
|
1005
|
+
* sessionPublicKey: session.publicKey
|
|
1006
|
+
* }, bearerToken);
|
|
1007
|
+
* ```
|
|
1008
|
+
*/
|
|
1009
|
+
async revokeSessionKey(params, bearerToken) {
|
|
1010
|
+
const { encryptKey, wallet, sessionPublicKey } = params;
|
|
1011
|
+
this.validateChipiWallet(wallet.walletType, "Revoke", wallet.publicKey);
|
|
1012
|
+
try {
|
|
1013
|
+
console.log("[ChipiSDK:Session:Revoke] Revoking session from contract", {
|
|
1014
|
+
walletAddress: wallet.publicKey.slice(0, 15) + "...",
|
|
1015
|
+
sessionToRevoke: sessionPublicKey.slice(0, 15) + "..."
|
|
1016
|
+
});
|
|
1017
|
+
const txHash = await executePaymasterTransaction({
|
|
1018
|
+
params: {
|
|
1019
|
+
encryptKey,
|
|
1020
|
+
wallet: { ...wallet, walletType: "CHIPI" },
|
|
1021
|
+
calls: [
|
|
1022
|
+
{
|
|
1023
|
+
contractAddress: wallet.publicKey,
|
|
1024
|
+
entrypoint: shared.SESSION_ENTRYPOINTS.REVOKE,
|
|
1025
|
+
calldata: [sessionPublicKey]
|
|
1026
|
+
}
|
|
1027
|
+
],
|
|
1028
|
+
saveToDatabase: false
|
|
1029
|
+
// Don't record session management txs
|
|
1030
|
+
},
|
|
1031
|
+
bearerToken,
|
|
1032
|
+
client: this.client
|
|
1033
|
+
});
|
|
1034
|
+
console.log("[ChipiSDK:Session:Revoke] Session revoked successfully", {
|
|
1035
|
+
txHash,
|
|
1036
|
+
sessionRevoked: sessionPublicKey.slice(0, 15) + "..."
|
|
1037
|
+
});
|
|
1038
|
+
return txHash;
|
|
1039
|
+
} catch (error) {
|
|
1040
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
1041
|
+
console.error("[ChipiSDK:Session:Revoke] Revocation failed", {
|
|
1042
|
+
error: err.message,
|
|
1043
|
+
walletAddress: wallet.publicKey?.slice(0, 15) + "...",
|
|
1044
|
+
sessionToRevoke: sessionPublicKey?.slice(0, 15) + "..."
|
|
1045
|
+
});
|
|
1046
|
+
throw error;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Query session data from the smart contract.
|
|
1051
|
+
*
|
|
1052
|
+
* This is a read-only call that does not require signing or gas.
|
|
1053
|
+
*
|
|
1054
|
+
* @param params - Query parameters
|
|
1055
|
+
* @returns Session data including status, remaining calls, and allowed entrypoints
|
|
1056
|
+
*
|
|
1057
|
+
* @example
|
|
1058
|
+
* ```typescript
|
|
1059
|
+
* const sessionData = await sdk.sessions.getSessionData({
|
|
1060
|
+
* walletAddress: userWallet.publicKey,
|
|
1061
|
+
* sessionPublicKey: session.publicKey
|
|
1062
|
+
* });
|
|
1063
|
+
* if (sessionData.isActive) {
|
|
1064
|
+
* console.log(`Session has ${sessionData.remainingCalls} calls remaining`);
|
|
1065
|
+
* }
|
|
1066
|
+
* ```
|
|
1067
|
+
*
|
|
1068
|
+
* NOTE: This method intentionally does NOT validate walletType because:
|
|
1069
|
+
* 1. It's a read-only query - no state change or risk
|
|
1070
|
+
* 2. Non-CHIPI wallets will simply return isActive=false (graceful failure)
|
|
1071
|
+
* 3. It doesn't require walletType parameter at all - only walletAddress
|
|
1072
|
+
* Adding validation would require changing the interface for no functional benefit.
|
|
1073
|
+
*/
|
|
1074
|
+
async getSessionData(params) {
|
|
1075
|
+
const { walletAddress, sessionPublicKey } = params;
|
|
1076
|
+
try {
|
|
1077
|
+
const provider = new starknet.RpcProvider({
|
|
1078
|
+
nodeUrl: shared.WALLET_RPC_ENDPOINTS["CHIPI"]
|
|
1079
|
+
});
|
|
1080
|
+
console.log("[ChipiSDK:Session:GetData] Querying session data", {
|
|
1081
|
+
walletAddress: walletAddress.slice(0, 15) + "...",
|
|
1082
|
+
sessionPubKey: sessionPublicKey.slice(0, 15) + "..."
|
|
1083
|
+
});
|
|
1084
|
+
const result = await provider.callContract({
|
|
1085
|
+
contractAddress: walletAddress,
|
|
1086
|
+
entrypoint: shared.SESSION_ENTRYPOINTS.GET_DATA,
|
|
1087
|
+
calldata: [sessionPublicKey]
|
|
1088
|
+
});
|
|
1089
|
+
const resultArray = Array.isArray(result) ? result : result.result || [];
|
|
1090
|
+
if (resultArray.length < 4) {
|
|
1091
|
+
console.warn("[ChipiSDK:Session:GetData] Unexpected response format", {
|
|
1092
|
+
resultLength: resultArray.length,
|
|
1093
|
+
result: resultArray
|
|
1094
|
+
});
|
|
1095
|
+
return {
|
|
1096
|
+
isActive: false,
|
|
1097
|
+
validUntil: 0,
|
|
1098
|
+
remainingCalls: 0,
|
|
1099
|
+
allowedEntrypoints: []
|
|
1100
|
+
};
|
|
1101
|
+
}
|
|
1102
|
+
const isActive = resultArray[0] === "0x1";
|
|
1103
|
+
const validUntil = Number(BigInt(resultArray[1]));
|
|
1104
|
+
const remainingCalls = Number(BigInt(resultArray[2]));
|
|
1105
|
+
const entrypointsLen = Number(BigInt(resultArray[3]));
|
|
1106
|
+
const allowedEntrypoints = resultArray.slice(4, 4 + entrypointsLen);
|
|
1107
|
+
const sessionData = {
|
|
1108
|
+
isActive,
|
|
1109
|
+
validUntil,
|
|
1110
|
+
remainingCalls,
|
|
1111
|
+
allowedEntrypoints
|
|
1112
|
+
};
|
|
1113
|
+
console.log("[ChipiSDK:Session:GetData] Session data retrieved", {
|
|
1114
|
+
isActive,
|
|
1115
|
+
validUntil: new Date(validUntil * 1e3).toISOString(),
|
|
1116
|
+
remainingCalls,
|
|
1117
|
+
allowedEntrypointsCount: allowedEntrypoints.length
|
|
1118
|
+
});
|
|
1119
|
+
return sessionData;
|
|
1120
|
+
} catch (error) {
|
|
1121
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
1122
|
+
console.error("[ChipiSDK:Session:GetData] Query failed", {
|
|
1123
|
+
error: err.message,
|
|
1124
|
+
walletAddress: walletAddress?.slice(0, 15) + "...",
|
|
1125
|
+
sessionPubKey: sessionPublicKey?.slice(0, 15) + "..."
|
|
1126
|
+
});
|
|
1127
|
+
return {
|
|
1128
|
+
isActive: false,
|
|
1129
|
+
validUntil: 0,
|
|
1130
|
+
remainingCalls: 0,
|
|
1131
|
+
allowedEntrypoints: []
|
|
1132
|
+
};
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
/**
|
|
1136
|
+
* Execute a gasless transaction using a session key.
|
|
1137
|
+
*
|
|
1138
|
+
* This uses the 4-element session signature format instead of owner signature.
|
|
1139
|
+
* The session must be:
|
|
1140
|
+
* 1. Generated via `createSessionKey()`
|
|
1141
|
+
* 2. Registered on-chain via `addSessionKeyToContract()`
|
|
1142
|
+
*
|
|
1143
|
+
* CHIPI wallets only - will throw if wallet type is not CHIPI.
|
|
1144
|
+
*
|
|
1145
|
+
* @param params - Session execution parameters
|
|
1146
|
+
* @param bearerToken - Authentication token
|
|
1147
|
+
* @returns Transaction hash
|
|
1148
|
+
*
|
|
1149
|
+
* @example
|
|
1150
|
+
* ```typescript
|
|
1151
|
+
* // 1. Create session key (store externally)
|
|
1152
|
+
* const session = sdk.sessions.createSessionKey({ encryptKey });
|
|
1153
|
+
*
|
|
1154
|
+
* // 2. Register on contract (one-time)
|
|
1155
|
+
* await sdk.sessions.addSessionKeyToContract({
|
|
1156
|
+
* encryptKey,
|
|
1157
|
+
* wallet,
|
|
1158
|
+
* sessionConfig: {
|
|
1159
|
+
* sessionPublicKey: session.publicKey,
|
|
1160
|
+
* validUntil: session.validUntil,
|
|
1161
|
+
* maxCalls: 1000,
|
|
1162
|
+
* allowedEntrypoints: []
|
|
1163
|
+
* }
|
|
1164
|
+
* }, bearerToken);
|
|
1165
|
+
*
|
|
1166
|
+
* // 3. Execute transactions with session (no owner key needed)
|
|
1167
|
+
* const txHash = await sdk.sessions.executeTransactionWithSession({
|
|
1168
|
+
* encryptKey,
|
|
1169
|
+
* wallet,
|
|
1170
|
+
* session,
|
|
1171
|
+
* calls
|
|
1172
|
+
* }, bearerToken);
|
|
1173
|
+
* ```
|
|
1174
|
+
*/
|
|
1175
|
+
async executeTransactionWithSession(params, bearerToken) {
|
|
1176
|
+
const { encryptKey, wallet, session, calls } = params;
|
|
1177
|
+
if (wallet.walletType && wallet.walletType !== "CHIPI") {
|
|
1178
|
+
throw new shared.ChipiSessionError(
|
|
1179
|
+
`Session execution only supports CHIPI wallets. Got: ${wallet.walletType}`,
|
|
1180
|
+
shared.SESSION_ERRORS.INVALID_WALLET_TYPE_FOR_SESSION
|
|
1181
|
+
);
|
|
1182
|
+
}
|
|
1183
|
+
return executePaymasterTransactionWithSession({
|
|
1184
|
+
params: {
|
|
1185
|
+
encryptKey,
|
|
1186
|
+
wallet: { ...wallet, walletType: "CHIPI" },
|
|
1187
|
+
session,
|
|
1188
|
+
calls,
|
|
1189
|
+
saveToDatabase: true
|
|
1190
|
+
},
|
|
1191
|
+
bearerToken,
|
|
1192
|
+
client: this.client
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
1195
|
+
};
|
|
673
1196
|
|
|
674
1197
|
// src/chipi-sdk.ts
|
|
675
1198
|
var ChipiSDK = class {
|
|
@@ -682,7 +1205,9 @@ var ChipiSDK = class {
|
|
|
682
1205
|
this.skuTransactions = new ChipiSkuTransactions(this.client);
|
|
683
1206
|
this.skus = new ChipiSkus(this.client);
|
|
684
1207
|
this.users = new Users(this.client);
|
|
1208
|
+
this.sessions = new ChipiSessions(this.client);
|
|
685
1209
|
this.executeTransaction = this.executeTransaction.bind(this);
|
|
1210
|
+
this.executeTransactionWithSession = this.executeTransactionWithSession.bind(this);
|
|
686
1211
|
this.transfer = this.transfer.bind(this);
|
|
687
1212
|
this.approve = this.approve.bind(this);
|
|
688
1213
|
this.stakeVesuUsdc = this.stakeVesuUsdc.bind(this);
|
|
@@ -716,6 +1241,49 @@ var ChipiSDK = class {
|
|
|
716
1241
|
bearerToken: this.resolveBearerToken(bearerToken)
|
|
717
1242
|
});
|
|
718
1243
|
}
|
|
1244
|
+
/**
|
|
1245
|
+
* Execute a gasless transaction using a session key.
|
|
1246
|
+
*
|
|
1247
|
+
* This uses the 4-element session signature format instead of owner signature.
|
|
1248
|
+
* The session must be:
|
|
1249
|
+
* 1. Generated via `sessions.createSessionKey()`
|
|
1250
|
+
* 2. Registered on-chain via `sessions.addSessionKeyToContract()`
|
|
1251
|
+
*
|
|
1252
|
+
* CHIPI wallets only - will throw if wallet type is not CHIPI.
|
|
1253
|
+
*
|
|
1254
|
+
* @example
|
|
1255
|
+
* ```typescript
|
|
1256
|
+
* // 1. Create session key (store externally)
|
|
1257
|
+
* const session = sdk.sessions.createSessionKey({ encryptKey });
|
|
1258
|
+
*
|
|
1259
|
+
* // 2. Register on contract (one-time)
|
|
1260
|
+
* await sdk.sessions.addSessionKeyToContract({
|
|
1261
|
+
* encryptKey,
|
|
1262
|
+
* wallet,
|
|
1263
|
+
* sessionConfig: {
|
|
1264
|
+
* sessionPublicKey: session.publicKey,
|
|
1265
|
+
* validUntil: session.validUntil,
|
|
1266
|
+
* maxCalls: 1000,
|
|
1267
|
+
* allowedEntrypoints: []
|
|
1268
|
+
* }
|
|
1269
|
+
* }, bearerToken);
|
|
1270
|
+
*
|
|
1271
|
+
* // 3. Execute transactions with session (no owner key needed)
|
|
1272
|
+
* const txHash = await sdk.executeTransactionWithSession({
|
|
1273
|
+
* params: { encryptKey, wallet, session, calls },
|
|
1274
|
+
* bearerToken
|
|
1275
|
+
* });
|
|
1276
|
+
* ```
|
|
1277
|
+
*/
|
|
1278
|
+
async executeTransactionWithSession({
|
|
1279
|
+
params,
|
|
1280
|
+
bearerToken
|
|
1281
|
+
}) {
|
|
1282
|
+
return this.sessions.executeTransactionWithSession(
|
|
1283
|
+
params,
|
|
1284
|
+
this.resolveBearerToken(bearerToken)
|
|
1285
|
+
);
|
|
1286
|
+
}
|
|
719
1287
|
/**
|
|
720
1288
|
* Transfer tokens
|
|
721
1289
|
*/
|
|
@@ -916,6 +1484,7 @@ exports.ChipiBrowserSDK = ChipiBrowserSDK;
|
|
|
916
1484
|
exports.ChipiClient = ChipiClient;
|
|
917
1485
|
exports.ChipiSDK = ChipiSDK;
|
|
918
1486
|
exports.ChipiServerSDK = ChipiServerSDK;
|
|
1487
|
+
exports.ChipiSessions = ChipiSessions;
|
|
919
1488
|
exports.ChipiSkuTransactions = ChipiSkuTransactions;
|
|
920
1489
|
exports.ChipiSkus = ChipiSkus;
|
|
921
1490
|
exports.ChipiTransactions = ChipiTransactions;
|