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