@veridex/sdk 1.1.6 → 1.1.7
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/{EVMClient-CTOtNY8I.d.mts → EVMClient-DqDiFak8.d.mts} +1 -1
- package/dist/auth/prepareAuth.d.mts +5 -4
- package/dist/auth/prepareAuth.js +57 -1415
- package/dist/auth/prepareAuth.js.map +1 -1
- package/dist/auth/prepareAuth.mjs +17 -96
- package/dist/auth/prepareAuth.mjs.map +1 -1
- package/dist/chains/aptos/index.d.mts +1 -1
- package/dist/chains/aptos/index.js +11 -33
- package/dist/chains/aptos/index.js.map +1 -1
- package/dist/chains/aptos/index.mjs +2 -2
- package/dist/chains/avalanche/index.d.mts +2 -2
- package/dist/chains/avalanche/index.js +19 -115
- package/dist/chains/avalanche/index.js.map +1 -1
- package/dist/chains/avalanche/index.mjs +3 -3
- package/dist/chains/evm/index.d.mts +3 -3
- package/dist/chains/evm/index.js +19 -115
- package/dist/chains/evm/index.js.map +1 -1
- package/dist/chains/evm/index.mjs +2 -2
- package/dist/chains/solana/index.d.mts +1 -1
- package/dist/chains/solana/index.js +11 -33
- package/dist/chains/solana/index.js.map +1 -1
- package/dist/chains/solana/index.mjs +2 -2
- package/dist/chains/stacks/index.d.mts +1 -1
- package/dist/chains/stacks/index.js +11 -38
- package/dist/chains/stacks/index.js.map +1 -1
- package/dist/chains/stacks/index.mjs +2 -2
- package/dist/chains/starknet/index.d.mts +36 -2
- package/dist/chains/starknet/index.js +208 -37
- package/dist/chains/starknet/index.js.map +1 -1
- package/dist/chains/starknet/index.mjs +9 -4
- package/dist/chains/sui/index.d.mts +1 -1
- package/dist/chains/sui/index.js +11 -27
- package/dist/chains/sui/index.js.map +1 -1
- package/dist/chains/sui/index.mjs +2 -2
- package/dist/{chunk-ZNIVNPGF.mjs → chunk-3PCAVZUZ.mjs} +173 -37
- package/dist/chunk-3PCAVZUZ.mjs.map +1 -0
- package/dist/{chunk-DQOW3G7M.mjs → chunk-6BINP4RT.mjs} +48 -9
- package/dist/{chunk-DQOW3G7M.mjs.map → chunk-6BINP4RT.mjs.map} +1 -1
- package/dist/{chunk-7KN6Y4GX.mjs → chunk-AK5HWYX4.mjs} +12 -40
- package/dist/chunk-AK5HWYX4.mjs.map +1 -0
- package/dist/{chunk-QVTADARB.mjs → chunk-FPSCAGYS.mjs} +12 -35
- package/dist/chunk-FPSCAGYS.mjs.map +1 -0
- package/dist/{chunk-USVZH4QC.mjs → chunk-H3WRT6Y4.mjs} +20 -117
- package/dist/chunk-H3WRT6Y4.mjs.map +1 -0
- package/dist/{chunk-GXJUY2SC.mjs → chunk-MNH22BM2.mjs} +12 -35
- package/dist/chunk-MNH22BM2.mjs.map +1 -0
- package/dist/chunk-N42LPFPJ.mjs +177 -0
- package/dist/chunk-N42LPFPJ.mjs.map +1 -0
- package/dist/{chunk-D57UJ4L5.mjs → chunk-NKSRF45N.mjs} +12 -29
- package/dist/chunk-NKSRF45N.mjs.map +1 -0
- package/dist/{chunk-2CALEUER.mjs → chunk-SKZLZFE2.mjs} +5 -58
- package/dist/chunk-SKZLZFE2.mjs.map +1 -0
- package/dist/{chunk-NVRAQPSF.mjs → chunk-UF5NWMSQ.mjs} +20 -4
- package/dist/chunk-UF5NWMSQ.mjs.map +1 -0
- package/dist/chunk-WC4X3MAO.mjs +58 -0
- package/dist/chunk-WC4X3MAO.mjs.map +1 -0
- package/dist/{chunk-5FH67KLG.mjs → chunk-XHDOSV2F.mjs} +2 -2
- package/dist/{index-9ercn1sa.d.mts → index-D1nb2JV9.d.mts} +1 -1
- package/dist/index-qyOqd8tx.d.mts +517 -0
- package/dist/index.d.mts +27 -364
- package/dist/index.js +2316 -2473
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +978 -51
- package/dist/index.mjs.map +1 -1
- package/dist/passkey.mjs +2 -1
- package/dist/payload.d.mts +22 -28
- package/dist/payload.js +50 -9
- package/dist/payload.js.map +1 -1
- package/dist/payload.mjs +7 -3
- package/dist/platform/index.d.mts +3 -0
- package/dist/platform/index.js +216 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/index.mjs +21 -0
- package/dist/platform/index.mjs.map +1 -0
- package/dist/{portfolio-W2FQ2G3O.mjs → portfolio-MLP2JIFK.mjs} +2 -3
- package/dist/queries/index.mjs +324 -10
- package/dist/queries/index.mjs.map +1 -1
- package/dist/{types-DQ5dtU9x.d.mts → types-CdlEbixV.d.mts} +11 -1
- package/package.json +7 -1
- package/dist/chunk-2CALEUER.mjs.map +0 -1
- package/dist/chunk-72ZA3OYQ.mjs +0 -20
- package/dist/chunk-72ZA3OYQ.mjs.map +0 -1
- package/dist/chunk-7KN6Y4GX.mjs.map +0 -1
- package/dist/chunk-D57UJ4L5.mjs.map +0 -1
- package/dist/chunk-GXJUY2SC.mjs.map +0 -1
- package/dist/chunk-NVRAQPSF.mjs.map +0 -1
- package/dist/chunk-QVTADARB.mjs.map +0 -1
- package/dist/chunk-USVZH4QC.mjs.map +0 -1
- package/dist/chunk-XDIIFIW6.mjs +0 -330
- package/dist/chunk-XDIIFIW6.mjs.map +0 -1
- package/dist/chunk-ZNIVNPGF.mjs.map +0 -1
- package/dist/chunk-ZXMTPBSP.mjs +0 -857
- package/dist/chunk-ZXMTPBSP.mjs.map +0 -1
- /package/dist/{chunk-5FH67KLG.mjs.map → chunk-XHDOSV2F.mjs.map} +0 -0
- /package/dist/{portfolio-W2FQ2G3O.mjs.map → portfolio-MLP2JIFK.mjs.map} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as SessionKey } from '../../types-C564CfsE.mjs';
|
|
2
|
-
import { C as ChainClient, a as ChainConfig, T as TransferParams, E as ExecuteParams, B as BridgeParams, W as WebAuthnSignature,
|
|
2
|
+
import { C as ChainClient, a as ChainConfig, T as TransferParams, E as ExecuteParams, B as BridgeParams, W as WebAuthnSignature, b as DispatchResult, V as VaultCreationResult, y as RegisterSessionParams, z as RevokeSessionParams, S as SessionValidationResult } from '../../types-CdlEbixV.mjs';
|
|
3
3
|
import { RpcProvider } from 'starknet';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -35,6 +35,13 @@ interface StarknetClientConfig {
|
|
|
35
35
|
hubRpcUrl?: string;
|
|
36
36
|
hubContractAddress?: string;
|
|
37
37
|
}
|
|
38
|
+
interface StarknetSessionTransferParams {
|
|
39
|
+
session: SessionKey;
|
|
40
|
+
recipient: string;
|
|
41
|
+
amount: bigint;
|
|
42
|
+
relayerUrl: string;
|
|
43
|
+
validForSeconds?: number;
|
|
44
|
+
}
|
|
38
45
|
declare class StarknetClient implements ChainClient {
|
|
39
46
|
private config;
|
|
40
47
|
private provider;
|
|
@@ -85,6 +92,7 @@ declare class StarknetClient implements ChainClient {
|
|
|
85
92
|
* @throws Error - Session management must be done via Hub chain
|
|
86
93
|
*/
|
|
87
94
|
revokeSession(_params: RevokeSessionParams): Promise<void>;
|
|
95
|
+
executeSessionTransfer(params: StarknetSessionTransferParams): Promise<DispatchResult>;
|
|
88
96
|
/**
|
|
89
97
|
* Check if a session is active by querying the Hub
|
|
90
98
|
* This method queries the Hub contract directly for session validation
|
|
@@ -168,4 +176,30 @@ declare class StarknetClient implements ChainClient {
|
|
|
168
176
|
isProtocolPaused(): Promise<boolean>;
|
|
169
177
|
}
|
|
170
178
|
|
|
171
|
-
|
|
179
|
+
interface StarknetSessionTransferContext {
|
|
180
|
+
spokeAddress: string;
|
|
181
|
+
vaultAddress: string;
|
|
182
|
+
authorizedCaller: string;
|
|
183
|
+
userKeyHash: string;
|
|
184
|
+
nonceCounter: bigint;
|
|
185
|
+
validUntil: bigint;
|
|
186
|
+
recipient: string;
|
|
187
|
+
amount: bigint;
|
|
188
|
+
}
|
|
189
|
+
interface StarknetSessionTransferSignature {
|
|
190
|
+
digest: string;
|
|
191
|
+
sessionKeyHash: string;
|
|
192
|
+
publicKeyX: string;
|
|
193
|
+
publicKeyY: string;
|
|
194
|
+
r: string;
|
|
195
|
+
s: string;
|
|
196
|
+
}
|
|
197
|
+
declare function buildStarknetSessionTransferChallenge(context: StarknetSessionTransferContext, publicKey: Uint8Array): {
|
|
198
|
+
digest: string;
|
|
199
|
+
sessionKeyHash: string;
|
|
200
|
+
publicKeyX: string;
|
|
201
|
+
publicKeyY: string;
|
|
202
|
+
};
|
|
203
|
+
declare function signStarknetSessionTransfer(context: StarknetSessionTransferContext, privateKey: Uint8Array): StarknetSessionTransferSignature;
|
|
204
|
+
|
|
205
|
+
export { StarknetClient, type StarknetClientConfig, type StarknetSessionTransferContext, type StarknetSessionTransferParams, type StarknetSessionTransferSignature, buildStarknetSessionTransferChallenge, signStarknetSessionTransfer };
|
|
@@ -20,11 +20,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/chains/starknet/index.ts
|
|
21
21
|
var starknet_exports = {};
|
|
22
22
|
__export(starknet_exports, {
|
|
23
|
-
StarknetClient: () => StarknetClient
|
|
23
|
+
StarknetClient: () => StarknetClient,
|
|
24
|
+
buildStarknetSessionTransferChallenge: () => buildStarknetSessionTransferChallenge,
|
|
25
|
+
signStarknetSessionTransfer: () => signStarknetSessionTransfer
|
|
24
26
|
});
|
|
25
27
|
module.exports = __toCommonJS(starknet_exports);
|
|
26
28
|
|
|
27
29
|
// src/chains/starknet/StarknetClient.ts
|
|
30
|
+
var import_ethers3 = require("ethers");
|
|
28
31
|
var import_crypto = require("crypto");
|
|
29
32
|
var import_starknet = require("starknet");
|
|
30
33
|
|
|
@@ -101,6 +104,123 @@ function padTo32Bytes(address) {
|
|
|
101
104
|
}
|
|
102
105
|
return "0x" + hex.padStart(64, "0");
|
|
103
106
|
}
|
|
107
|
+
var CHALLENGE_DOMAIN = import_ethers.ethers.sha256(import_ethers.ethers.toUtf8Bytes("veridex.challenge.v1"));
|
|
108
|
+
|
|
109
|
+
// src/core/relayerUrl.ts
|
|
110
|
+
var API_ROOT = "/api/v1";
|
|
111
|
+
function trimTrailingSlashes(value) {
|
|
112
|
+
return value.trim().replace(/\/+$/, "");
|
|
113
|
+
}
|
|
114
|
+
function buildRelayerApiUrl(baseUrl, path) {
|
|
115
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
116
|
+
const trimmed = trimTrailingSlashes(baseUrl);
|
|
117
|
+
if (!trimmed) {
|
|
118
|
+
return `${API_ROOT}${normalizedPath}`;
|
|
119
|
+
}
|
|
120
|
+
if (trimmed.startsWith("/")) {
|
|
121
|
+
if (/\/api\/v1$/i.test(trimmed) || /\/api\/auth\/relay$/i.test(trimmed)) {
|
|
122
|
+
return `${trimmed}${normalizedPath}`;
|
|
123
|
+
}
|
|
124
|
+
return `${trimmed}${normalizedPath}`;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
const url = new URL(trimmed);
|
|
128
|
+
if (/\/api\/v1$/i.test(url.pathname) || /\/api\/auth\/relay$/i.test(url.pathname)) {
|
|
129
|
+
url.pathname = `${url.pathname.replace(/\/+$/, "")}${normalizedPath}`;
|
|
130
|
+
return url.toString();
|
|
131
|
+
}
|
|
132
|
+
if (!url.pathname || url.pathname === "/") {
|
|
133
|
+
url.pathname = `${API_ROOT}${normalizedPath}`;
|
|
134
|
+
return url.toString();
|
|
135
|
+
}
|
|
136
|
+
url.pathname = `${url.pathname.replace(/\/+$/, "")}${normalizedPath}`;
|
|
137
|
+
return url.toString();
|
|
138
|
+
} catch {
|
|
139
|
+
if (/\/api\/v1$/i.test(trimmed) || /\/api\/auth\/relay$/i.test(trimmed)) {
|
|
140
|
+
return `${trimmed}${normalizedPath}`;
|
|
141
|
+
}
|
|
142
|
+
return `${trimmed}${API_ROOT}${normalizedPath}`;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/chains/starknet/session.ts
|
|
147
|
+
var import_ethers2 = require("ethers");
|
|
148
|
+
var STARKNET_VERIDEX_CHAIN_ID = 4;
|
|
149
|
+
var TIER_T1_ATTESTED = 2;
|
|
150
|
+
var SESSION_ACTION_VERSION = 1;
|
|
151
|
+
var SESSION_ACTION_DOMAIN = import_ethers2.ethers.keccak256(
|
|
152
|
+
import_ethers2.ethers.toUtf8Bytes("veridex.session.action.v1")
|
|
153
|
+
);
|
|
154
|
+
var CHALLENGE_DOMAIN2 = import_ethers2.ethers.sha256(import_ethers2.ethers.toUtf8Bytes("veridex.challenge.v1"));
|
|
155
|
+
function buildStarknetSessionTransferChallenge(context, publicKey) {
|
|
156
|
+
if (publicKey.length !== 65 || publicKey[0] !== 4) {
|
|
157
|
+
throw new Error("Starknet session public key must be 65-byte uncompressed secp256k1");
|
|
158
|
+
}
|
|
159
|
+
if (context.nonceCounter < 0n || context.nonceCounter > 0xffffffffffffffffn) {
|
|
160
|
+
throw new Error("Starknet session nonce must fit u64");
|
|
161
|
+
}
|
|
162
|
+
if (context.validUntil <= 0n || context.validUntil > 0xffffffffffffffffn) {
|
|
163
|
+
throw new Error("Starknet session validUntil must fit non-zero u64");
|
|
164
|
+
}
|
|
165
|
+
if (context.amount <= 0n) {
|
|
166
|
+
throw new Error("Starknet session transfer amount must be positive");
|
|
167
|
+
}
|
|
168
|
+
const publicKeyX = import_ethers2.ethers.hexlify(publicKey.slice(1, 33));
|
|
169
|
+
const publicKeyY = import_ethers2.ethers.hexlify(publicKey.slice(33, 65));
|
|
170
|
+
const sessionKeyHash = import_ethers2.ethers.keccak256(publicKey);
|
|
171
|
+
const actionHash = import_ethers2.ethers.solidityPackedKeccak256(
|
|
172
|
+
["uint8", "bytes32", "bytes32", "uint256"],
|
|
173
|
+
[1, import_ethers2.ethers.ZeroHash, toBytes32(context.recipient), context.amount]
|
|
174
|
+
);
|
|
175
|
+
const actionCommitment = import_ethers2.ethers.solidityPackedKeccak256(
|
|
176
|
+
["bytes32", "uint8", "bytes32", "bytes32", "bytes32", "bytes32", "uint64", "bytes32"],
|
|
177
|
+
[
|
|
178
|
+
SESSION_ACTION_DOMAIN,
|
|
179
|
+
SESSION_ACTION_VERSION,
|
|
180
|
+
toBytes32(context.userKeyHash),
|
|
181
|
+
sessionKeyHash,
|
|
182
|
+
toBytes32(context.vaultAddress),
|
|
183
|
+
toBytes32(context.authorizedCaller),
|
|
184
|
+
context.validUntil,
|
|
185
|
+
actionHash
|
|
186
|
+
]
|
|
187
|
+
);
|
|
188
|
+
const digest = import_ethers2.ethers.sha256(import_ethers2.ethers.solidityPacked(
|
|
189
|
+
["bytes32", "uint8", "uint8", "uint32", "bytes32", "uint32", "uint64", "bytes32"],
|
|
190
|
+
[
|
|
191
|
+
CHALLENGE_DOMAIN2,
|
|
192
|
+
1,
|
|
193
|
+
TIER_T1_ATTESTED,
|
|
194
|
+
STARKNET_VERIDEX_CHAIN_ID,
|
|
195
|
+
toBytes32(context.spokeAddress),
|
|
196
|
+
STARKNET_VERIDEX_CHAIN_ID,
|
|
197
|
+
context.nonceCounter,
|
|
198
|
+
actionCommitment
|
|
199
|
+
]
|
|
200
|
+
));
|
|
201
|
+
return { digest, sessionKeyHash, publicKeyX, publicKeyY };
|
|
202
|
+
}
|
|
203
|
+
function signStarknetSessionTransfer(context, privateKey) {
|
|
204
|
+
if (privateKey.length !== 32) {
|
|
205
|
+
throw new Error("Starknet session private key must be 32 bytes");
|
|
206
|
+
}
|
|
207
|
+
const signingKey = new import_ethers2.ethers.SigningKey(privateKey);
|
|
208
|
+
const publicKey = import_ethers2.ethers.getBytes(signingKey.publicKey);
|
|
209
|
+
const challenge = buildStarknetSessionTransferChallenge(context, publicKey);
|
|
210
|
+
const signature = signingKey.sign(challenge.digest);
|
|
211
|
+
return {
|
|
212
|
+
...challenge,
|
|
213
|
+
r: signature.r,
|
|
214
|
+
s: signature.s
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function toBytes32(value) {
|
|
218
|
+
const bytes = import_ethers2.ethers.getBytes(value);
|
|
219
|
+
if (bytes.length > 32) {
|
|
220
|
+
throw new Error(`Value exceeds 32 bytes: ${value}`);
|
|
221
|
+
}
|
|
222
|
+
return import_ethers2.ethers.zeroPadValue(bytes, 32);
|
|
223
|
+
}
|
|
104
224
|
|
|
105
225
|
// src/chains/starknet/StarknetClient.ts
|
|
106
226
|
var U128_MAX = BigInt("0x100000000000000000000000000000000");
|
|
@@ -167,41 +287,16 @@ var StarknetClient = class {
|
|
|
167
287
|
);
|
|
168
288
|
}
|
|
169
289
|
async dispatchGasless(signature, publicKeyX, publicKeyY, targetChain, actionPayload, nonce, relayerUrl) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
publicKeyX: "0x" + publicKeyX.toString(16).padStart(64, "0"),
|
|
181
|
-
publicKeyY: "0x" + publicKeyY.toString(16).padStart(64, "0"),
|
|
182
|
-
targetChain,
|
|
183
|
-
// 50001 for Starknet
|
|
184
|
-
actionPayload,
|
|
185
|
-
userNonce: Number(nonce)
|
|
186
|
-
};
|
|
187
|
-
const response = await fetch(`${relayerUrl}/api/v1/submit`, {
|
|
188
|
-
method: "POST",
|
|
189
|
-
headers: { "Content-Type": "application/json" },
|
|
190
|
-
body: JSON.stringify(request)
|
|
191
|
-
});
|
|
192
|
-
if (!response.ok) {
|
|
193
|
-
const errorText = await response.text().catch(() => "Unknown error");
|
|
194
|
-
throw new Error(
|
|
195
|
-
`Relayer submission failed: ${response.status} ${response.statusText}. Error: ${errorText}`
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
const result = await response.json();
|
|
199
|
-
return {
|
|
200
|
-
transactionHash: result.transactionHash ?? result.txHash ?? result.hubTxHash,
|
|
201
|
-
sequence: BigInt(result.sequence || 0),
|
|
202
|
-
userKeyHash: keyHash,
|
|
203
|
-
targetChain
|
|
204
|
-
};
|
|
290
|
+
void signature;
|
|
291
|
+
void publicKeyX;
|
|
292
|
+
void publicKeyY;
|
|
293
|
+
void targetChain;
|
|
294
|
+
void actionPayload;
|
|
295
|
+
void nonce;
|
|
296
|
+
void relayerUrl;
|
|
297
|
+
throw new Error(
|
|
298
|
+
"ChainClient.dispatchGasless() cannot bind v3 destination metadata. Use VeridexSDK.transferViaRelayer() or bridgeViaRelayer()."
|
|
299
|
+
);
|
|
205
300
|
}
|
|
206
301
|
// Note: getVaultAddress is now defined in the Social Recovery section below
|
|
207
302
|
// with enhanced spoke contract querying support.
|
|
@@ -337,6 +432,80 @@ var StarknetClient = class {
|
|
|
337
432
|
"Session revocation must be performed on the Hub chain (Base). Use EVMClient connected to the Hub to call revokeSession()."
|
|
338
433
|
);
|
|
339
434
|
}
|
|
435
|
+
async executeSessionTransfer(params) {
|
|
436
|
+
const derivedPublicKey = new import_ethers3.ethers.SigningKey(params.session.privateKey).publicKey;
|
|
437
|
+
const storedPublicKey = import_ethers3.ethers.hexlify(params.session.publicKey);
|
|
438
|
+
if (derivedPublicKey.toLowerCase() !== storedPublicKey.toLowerCase()) {
|
|
439
|
+
throw new Error("Starknet session public and private keys do not match");
|
|
440
|
+
}
|
|
441
|
+
if (import_ethers3.ethers.keccak256(params.session.publicKey).toLowerCase() !== params.session.keyHash.toLowerCase()) {
|
|
442
|
+
throw new Error("Starknet session key hash does not match its public key");
|
|
443
|
+
}
|
|
444
|
+
const validForSeconds = params.validForSeconds ?? 60;
|
|
445
|
+
if (!Number.isSafeInteger(validForSeconds) || validForSeconds < 1 || validForSeconds > 600) {
|
|
446
|
+
throw new Error("Starknet session signature validity must be 1-600 seconds");
|
|
447
|
+
}
|
|
448
|
+
if (params.session.chainScopes.length > 0 && !params.session.chainScopes.includes(this.config.wormholeChainId)) {
|
|
449
|
+
throw new Error(`Session is not scoped to Starknet chain ${this.config.wormholeChainId}`);
|
|
450
|
+
}
|
|
451
|
+
if (params.session.maxValue === 0n || params.amount > params.session.maxValue) {
|
|
452
|
+
throw new Error("Starknet session transfer exceeds its bounded grant");
|
|
453
|
+
}
|
|
454
|
+
const contextUrl = new URL(buildRelayerApiUrl(params.relayerUrl, "/starknet/session/context"));
|
|
455
|
+
contextUrl.searchParams.set("chainId", String(this.config.wormholeChainId));
|
|
456
|
+
contextUrl.searchParams.set("userKeyHash", params.session.userKeyHash);
|
|
457
|
+
contextUrl.searchParams.set("sessionKeyHash", params.session.keyHash);
|
|
458
|
+
const contextResponse = await fetch(contextUrl);
|
|
459
|
+
if (!contextResponse.ok) {
|
|
460
|
+
throw new Error(`Failed to load Starknet session context: ${contextResponse.status}`);
|
|
461
|
+
}
|
|
462
|
+
const context = await contextResponse.json();
|
|
463
|
+
const nonceCounter = BigInt(context.nonceCounter);
|
|
464
|
+
const validUntil = BigInt(Math.floor(Date.now() / 1e3) + validForSeconds);
|
|
465
|
+
if (validUntil > BigInt(Math.floor(params.session.expiry / 1e3))) {
|
|
466
|
+
throw new Error("Starknet session signature deadline exceeds session expiry");
|
|
467
|
+
}
|
|
468
|
+
const signed = signStarknetSessionTransfer({
|
|
469
|
+
spokeAddress: context.spokeAddress,
|
|
470
|
+
vaultAddress: context.vaultAddress,
|
|
471
|
+
authorizedCaller: context.authorizedCaller,
|
|
472
|
+
userKeyHash: params.session.userKeyHash,
|
|
473
|
+
nonceCounter,
|
|
474
|
+
validUntil,
|
|
475
|
+
recipient: params.recipient,
|
|
476
|
+
amount: params.amount
|
|
477
|
+
}, params.session.privateKey);
|
|
478
|
+
const executeResponse = await fetch(
|
|
479
|
+
buildRelayerApiUrl(params.relayerUrl, "/starknet/session/execute"),
|
|
480
|
+
{
|
|
481
|
+
method: "POST",
|
|
482
|
+
headers: { "Content-Type": "application/json" },
|
|
483
|
+
body: JSON.stringify({
|
|
484
|
+
targetChain: this.config.wormholeChainId,
|
|
485
|
+
userKeyHash: params.session.userKeyHash,
|
|
486
|
+
sessionKeyHash: signed.sessionKeyHash,
|
|
487
|
+
sessionSignatureR: signed.r,
|
|
488
|
+
sessionSignatureS: signed.s,
|
|
489
|
+
sessionPublicKeyX: signed.publicKeyX,
|
|
490
|
+
sessionPublicKeyY: signed.publicKeyY,
|
|
491
|
+
nonceCounter: nonceCounter.toString(),
|
|
492
|
+
validUntil: validUntil.toString(),
|
|
493
|
+
recipient: params.recipient,
|
|
494
|
+
amount: params.amount.toString()
|
|
495
|
+
})
|
|
496
|
+
}
|
|
497
|
+
);
|
|
498
|
+
const result = await executeResponse.json();
|
|
499
|
+
if (!executeResponse.ok || !result.success) {
|
|
500
|
+
throw new Error(result.error ?? `Starknet session execution failed: ${executeResponse.status}`);
|
|
501
|
+
}
|
|
502
|
+
return {
|
|
503
|
+
transactionHash: result.transactionHash,
|
|
504
|
+
sequence: 0n,
|
|
505
|
+
userKeyHash: params.session.userKeyHash,
|
|
506
|
+
targetChain: this.config.wormholeChainId
|
|
507
|
+
};
|
|
508
|
+
}
|
|
340
509
|
/**
|
|
341
510
|
* Check if a session is active by querying the Hub
|
|
342
511
|
* This method queries the Hub contract directly for session validation
|
|
@@ -517,6 +686,8 @@ var StarknetClient = class {
|
|
|
517
686
|
};
|
|
518
687
|
// Annotate the CommonJS export names for ESM import in node:
|
|
519
688
|
0 && (module.exports = {
|
|
520
|
-
StarknetClient
|
|
689
|
+
StarknetClient,
|
|
690
|
+
buildStarknetSessionTransferChallenge,
|
|
691
|
+
signStarknetSessionTransfer
|
|
521
692
|
});
|
|
522
693
|
//# sourceMappingURL=index.js.map
|