@openfort/openfort-node 0.9.3 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/index.d.mts +274 -84
  3. package/dist/index.d.ts +274 -84
  4. package/dist/index.js +423 -35
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +423 -45
  7. package/dist/index.mjs.map +1 -1
  8. package/examples/evm/policies/createAccountPolicy.ts +68 -0
  9. package/examples/evm/policies/createProjectPolicy.ts +53 -0
  10. package/examples/evm/policies/deletePolicy.ts +34 -0
  11. package/examples/evm/policies/getPolicyById.ts +34 -0
  12. package/examples/evm/policies/listAccountPolicies.ts +11 -0
  13. package/examples/evm/policies/listPolicies.ts +11 -0
  14. package/examples/evm/policies/listProjectPolicies.ts +11 -0
  15. package/examples/evm/policies/signTypedDataPolicy.ts +35 -0
  16. package/examples/evm/policies/updatePolicy.ts +44 -0
  17. package/examples/evm/policies/validation.ts +45 -0
  18. package/examples/evm/transactions/sendTransaction.ts +44 -0
  19. package/examples/package.json +13 -0
  20. package/examples/pnpm-lock.yaml +933 -0
  21. package/examples/solana/policies/createSolAllowlistPolicy.ts +27 -0
  22. package/examples/solana/policies/createSolMessagePolicy.ts +29 -0
  23. package/examples/solana/policies/createSplTokenLimitsPolicy.ts +33 -0
  24. package/examples/solana/transactions/sendRawTransaction.ts +23 -0
  25. package/examples/solana/transactions/sendTransaction.ts +37 -0
  26. package/examples/solana/transactions/transfer.ts +44 -0
  27. package/knip.json +10 -1
  28. package/package.json +42 -4
  29. package/tsconfig.json +2 -3
  30. package/examples/policies/createAccountPolicy.ts +0 -71
  31. package/examples/policies/createEvmPolicy.ts +0 -149
  32. package/examples/policies/createSolanaPolicy.ts +0 -176
  33. package/examples/policies/createTypedDataPolicy.ts +0 -159
  34. package/examples/policies/deletePolicy.ts +0 -34
  35. package/examples/policies/getPolicy.ts +0 -41
  36. package/examples/policies/listPolicies.ts +0 -34
  37. package/examples/policies/multiRulePolicy.ts +0 -133
  38. package/examples/policies/updatePolicy.ts +0 -77
  39. package/examples/policies/validatePolicy.ts +0 -176
  40. /package/examples/{contracts → evm/contracts}/createContract.ts +0 -0
  41. /package/examples/{contracts → evm/contracts}/listContracts.ts +0 -0
  42. /package/examples/{transactions → evm/transactionIntents}/createTransactionIntent.ts +0 -0
  43. /package/examples/{transactions → evm/transactionIntents}/estimateGas.ts +0 -0
  44. /package/examples/{transactions → evm/transactionIntents}/getTransactionIntent.ts +0 -0
  45. /package/examples/{transactions → evm/transactionIntents}/listTransactionIntents.ts +0 -0
package/dist/index.mjs CHANGED
@@ -384,7 +384,7 @@ function requiresWalletAuth(requestMethod, requestPath) {
384
384
  }
385
385
 
386
386
  // src/version.ts
387
- var VERSION = "0.9.3";
387
+ var VERSION = "0.10.0";
388
388
  var PACKAGE = "@openfort/openfort-node";
389
389
 
390
390
  // src/openapi-client/openfortApiClient.ts
@@ -3785,15 +3785,6 @@ var decryptExportedPrivateKey = (encryptedPrivateKeyBase64, privateKeyPem) => {
3785
3785
  return decrypted.toString("hex");
3786
3786
  };
3787
3787
 
3788
- // src/wallets/evm/accounts/evmAccount.ts
3789
- import {
3790
- getTypesForEIP712Domain,
3791
- hashTypedData,
3792
- parseSignature,
3793
- serializeTransaction,
3794
- toPrefixedMessage
3795
- } from "viem";
3796
-
3797
3788
  // src/wallets/evm/actions/normalizeSignature.ts
3798
3789
  function normalizeSignature(sig) {
3799
3790
  const v = parseInt(sig.slice(-2), 16);
@@ -3829,29 +3820,53 @@ function toEvmAccount(data) {
3829
3820
  return result.signature;
3830
3821
  },
3831
3822
  async signMessage(parameters) {
3823
+ let viem;
3824
+ try {
3825
+ viem = await import("viem");
3826
+ } catch {
3827
+ throw new UserInputValidationError(
3828
+ "`viem` is required for signMessage. Install it and try again."
3829
+ );
3830
+ }
3832
3831
  const { message } = parameters;
3833
- const preimage = toPrefixedMessage(message);
3832
+ const preimage = viem.toPrefixedMessage(message);
3834
3833
  const result = await sign(id, { data: preimage });
3835
- return result.signature;
3834
+ return normalizeSignature(result.signature);
3836
3835
  },
3837
3836
  async signTransaction(transaction) {
3838
- const serialized = serializeTransaction(transaction);
3837
+ let viem;
3838
+ try {
3839
+ viem = await import("viem");
3840
+ } catch {
3841
+ throw new UserInputValidationError(
3842
+ "`viem` is required for signTransaction. Install it and try again."
3843
+ );
3844
+ }
3845
+ const serialized = viem.serializeTransaction(transaction);
3839
3846
  const response = await sign(id, { data: serialized });
3840
- const signature2 = parseSignature(response.signature);
3841
- const signedTransaction = serializeTransaction(
3847
+ const signature2 = viem.parseSignature(response.signature);
3848
+ const signedTransaction = viem.serializeTransaction(
3842
3849
  transaction,
3843
3850
  signature2
3844
3851
  );
3845
3852
  return signedTransaction;
3846
3853
  },
3847
3854
  async signTypedData(parameters) {
3855
+ let viem;
3856
+ try {
3857
+ viem = await import("viem");
3858
+ } catch {
3859
+ throw new UserInputValidationError(
3860
+ "`viem` is required for signTypedData. Install it and try again."
3861
+ );
3862
+ }
3848
3863
  const {
3849
3864
  domain = {},
3850
3865
  message,
3851
3866
  primaryType
3852
3867
  } = parameters;
3853
3868
  const types = {
3854
- EIP712Domain: getTypesForEIP712Domain({ domain }),
3869
+ EIP712Domain: viem.getTypesForEIP712Domain({ domain }),
3855
3870
  ...parameters.types
3856
3871
  };
3857
3872
  const openApiMessage = {
@@ -3860,9 +3875,9 @@ function toEvmAccount(data) {
3860
3875
  primaryType,
3861
3876
  message
3862
3877
  };
3863
- const hash = hashTypedData(openApiMessage);
3878
+ const hash = viem.hashTypedData(openApiMessage);
3864
3879
  const result = await sign(id, { data: hash });
3865
- return result.signature;
3880
+ return normalizeSignature(result.signature);
3866
3881
  }
3867
3882
  };
3868
3883
  return account;
@@ -3962,6 +3977,12 @@ var EvmClient = class {
3962
3977
  }
3963
3978
  throw new AccountNotFoundError();
3964
3979
  }
3980
+ /**
3981
+ * Retrieves delegated accounts linked to an EVM address on a specific chain.
3982
+ *
3983
+ * @param options - Options containing the address and chain ID
3984
+ * @returns List of linked accounts
3985
+ */
3965
3986
  async getLinkedAccounts(options) {
3966
3987
  const response = await getAccountsV2({
3967
3988
  address: options.address,
@@ -4100,6 +4121,198 @@ EvmClient.type = "evmWallet";
4100
4121
  // src/wallets/solana/solanaClient.ts
4101
4122
  import bs58 from "bs58";
4102
4123
 
4124
+ // src/wallets/solana/actions/constants.ts
4125
+ var USDC_MAINNET_MINT_ADDRESS = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
4126
+ var USDC_DEVNET_MINT_ADDRESS = "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU";
4127
+ var DEFAULT_COMPUTE_UNIT_LIMIT = 2e5;
4128
+ var DEFAULT_COMPUTE_UNIT_PRICE = 50000n;
4129
+
4130
+ // src/wallets/solana/actions/utils.ts
4131
+ function getUsdcMintAddress(cluster) {
4132
+ if (cluster === "mainnet-beta") {
4133
+ return USDC_MAINNET_MINT_ADDRESS;
4134
+ }
4135
+ return USDC_DEVNET_MINT_ADDRESS;
4136
+ }
4137
+ function getRpcEndpoint(cluster) {
4138
+ return cluster === "mainnet-beta" ? "https://api.mainnet-beta.solana.com" : "https://api.devnet.solana.com";
4139
+ }
4140
+ function getWsEndpoint(cluster) {
4141
+ return cluster === "mainnet-beta" ? "wss://api.mainnet-beta.solana.com" : "wss://api.devnet.solana.com";
4142
+ }
4143
+
4144
+ // src/wallets/solana/actions/sendTransaction.ts
4145
+ async function sendTransaction(options) {
4146
+ const {
4147
+ account,
4148
+ cluster,
4149
+ instructions,
4150
+ computeUnitLimit,
4151
+ computeUnitPrice,
4152
+ rpcUrl,
4153
+ wsUrl
4154
+ } = options;
4155
+ let solanaKit;
4156
+ let computeBudget;
4157
+ let transactionConfirmation;
4158
+ let koraModule;
4159
+ try {
4160
+ solanaKit = await import("@solana/kit");
4161
+ } catch {
4162
+ throw new UserInputValidationError(
4163
+ "`@solana/kit` is required for sendTransaction. Install it and try again."
4164
+ );
4165
+ }
4166
+ try {
4167
+ computeBudget = await import("@solana-program/compute-budget");
4168
+ } catch {
4169
+ throw new UserInputValidationError(
4170
+ "`@solana-program/compute-budget` is required for sendTransaction. Install it and try again."
4171
+ );
4172
+ }
4173
+ try {
4174
+ koraModule = await import("@solana/kora");
4175
+ } catch {
4176
+ throw new UserInputValidationError(
4177
+ "`@solana/kora` is required for sendTransaction. Install it and try again."
4178
+ );
4179
+ }
4180
+ try {
4181
+ transactionConfirmation = await import("@solana/transaction-confirmation");
4182
+ } catch {
4183
+ throw new UserInputValidationError(
4184
+ "`@solana/transaction-confirmation` is required for sendTransaction. Install it and try again."
4185
+ );
4186
+ }
4187
+ const userAddress = solanaKit.address(account.address);
4188
+ const clientConfig2 = getConfig();
4189
+ if (!clientConfig2?.publishableKey) {
4190
+ throw new MissingPublishableKeyError("sendTransaction");
4191
+ }
4192
+ const basePath = clientConfig2.basePath || "https://api.openfort.io";
4193
+ const client = new koraModule.KoraClient({
4194
+ rpcUrl: `${basePath}/rpc/solana/${cluster}`,
4195
+ apiKey: `Bearer ${clientConfig2.publishableKey}`
4196
+ });
4197
+ const rpc = solanaKit.createSolanaRpc(rpcUrl ?? getRpcEndpoint(cluster));
4198
+ const rpcSubscriptions = solanaKit.createSolanaRpcSubscriptions(
4199
+ wsUrl ?? getWsEndpoint(cluster)
4200
+ );
4201
+ const confirmTransaction = transactionConfirmation.createRecentSignatureConfirmationPromiseFactory({
4202
+ rpc,
4203
+ rpcSubscriptions
4204
+ });
4205
+ const { signer_address } = await client.getPayerSigner();
4206
+ const blockhashResponse = await client.getBlockhash();
4207
+ let txMsg = solanaKit.pipe(
4208
+ solanaKit.createTransactionMessage({ version: 0 }),
4209
+ (tx) => solanaKit.setTransactionMessageFeePayer(
4210
+ solanaKit.address(signer_address),
4211
+ tx
4212
+ ),
4213
+ // Kora's getBlockhash does not return lastValidBlockHeight, so we use 0n.
4214
+ // Transaction expiry is handled by the confirmTransaction timeout instead.
4215
+ (tx) => solanaKit.setTransactionMessageLifetimeUsingBlockhash(
4216
+ {
4217
+ blockhash: blockhashResponse.blockhash,
4218
+ lastValidBlockHeight: 0n
4219
+ },
4220
+ tx
4221
+ ),
4222
+ (tx) => solanaKit.appendTransactionMessageInstructions(instructions, tx),
4223
+ (tx) => computeBudget.updateOrAppendSetComputeUnitPriceInstruction(
4224
+ computeUnitPrice ?? DEFAULT_COMPUTE_UNIT_PRICE,
4225
+ tx
4226
+ ),
4227
+ (tx) => computeBudget.updateOrAppendSetComputeUnitLimitInstruction(
4228
+ computeUnitLimit ?? DEFAULT_COMPUTE_UNIT_LIMIT,
4229
+ tx
4230
+ )
4231
+ );
4232
+ if (computeUnitLimit === void 0) {
4233
+ const estimateComputeUnitLimit = computeBudget.estimateComputeUnitLimitFactory({ rpc });
4234
+ try {
4235
+ const estimatedLimit = await estimateComputeUnitLimit(txMsg);
4236
+ txMsg = computeBudget.updateOrAppendSetComputeUnitLimitInstruction(
4237
+ estimatedLimit,
4238
+ txMsg
4239
+ );
4240
+ } catch {
4241
+ }
4242
+ }
4243
+ const compiled = solanaKit.compileTransaction(txMsg);
4244
+ const messageBase64 = Buffer.from(
4245
+ compiled.messageBytes
4246
+ ).toString("base64");
4247
+ const signatureHex = await account.signTransaction({
4248
+ transaction: messageBase64
4249
+ });
4250
+ const sigBytes = new Uint8Array(
4251
+ Buffer.from(signatureHex.replace(/^0x/, ""), "hex")
4252
+ );
4253
+ const EMPTY_SIGNATURE = new Uint8Array(64);
4254
+ const signatures = Object.fromEntries(
4255
+ Object.entries(compiled.signatures).map(([addr]) => [
4256
+ addr,
4257
+ addr === userAddress ? sigBytes : EMPTY_SIGNATURE
4258
+ ])
4259
+ );
4260
+ const signed = { ...compiled, signatures };
4261
+ const base64Full = solanaKit.getBase64EncodedWireTransaction(signed);
4262
+ const { signed_transaction } = await client.signTransaction({
4263
+ transaction: base64Full,
4264
+ signer_key: signer_address
4265
+ });
4266
+ const signature2 = await rpc.sendTransaction(
4267
+ signed_transaction,
4268
+ { encoding: "base64" }
4269
+ ).send();
4270
+ await confirmTransaction({
4271
+ commitment: "confirmed",
4272
+ signature: signature2,
4273
+ abortSignal: AbortSignal.timeout(6e4)
4274
+ });
4275
+ return { signature: signature2 };
4276
+ }
4277
+
4278
+ // src/wallets/solana/actions/sendRawTransaction.ts
4279
+ async function sendRawTransaction(options) {
4280
+ const {
4281
+ account,
4282
+ cluster,
4283
+ transaction,
4284
+ computeUnitLimit,
4285
+ computeUnitPrice,
4286
+ rpcUrl,
4287
+ wsUrl
4288
+ } = options;
4289
+ let solanaKit;
4290
+ try {
4291
+ solanaKit = await import("@solana/kit");
4292
+ } catch {
4293
+ throw new UserInputValidationError(
4294
+ "`@solana/kit` is required for sendRawTransaction. Install it and try again."
4295
+ );
4296
+ }
4297
+ const txBytes = new Uint8Array(Buffer.from(transaction, "base64"));
4298
+ const decoded = solanaKit.getTransactionDecoder().decode(txBytes);
4299
+ const compiledMessage = solanaKit.getCompiledTransactionMessageDecoder().decode(decoded.messageBytes);
4300
+ const rpc = solanaKit.createSolanaRpc(rpcUrl ?? getRpcEndpoint(cluster));
4301
+ const decompiled = await solanaKit.decompileTransactionMessageFetchingLookupTables(
4302
+ compiledMessage,
4303
+ rpc
4304
+ );
4305
+ return sendTransaction({
4306
+ account,
4307
+ cluster,
4308
+ instructions: [...decompiled.instructions],
4309
+ computeUnitLimit,
4310
+ computeUnitPrice,
4311
+ rpcUrl,
4312
+ wsUrl
4313
+ });
4314
+ }
4315
+
4103
4316
  // src/wallets/solana/actions/signMessage.ts
4104
4317
  async function signMessage(options) {
4105
4318
  const { accountId, message } = options;
@@ -4122,6 +4335,150 @@ async function signTransaction(options) {
4122
4335
  };
4123
4336
  }
4124
4337
 
4338
+ // src/wallets/solana/actions/rpc.ts
4339
+ async function createRpcClient(cluster, rpcUrl) {
4340
+ let solanaKit;
4341
+ try {
4342
+ solanaKit = await import("@solana/kit");
4343
+ } catch {
4344
+ throw new UserInputValidationError(
4345
+ "`@solana/kit` is required. Install it and try again."
4346
+ );
4347
+ }
4348
+ return solanaKit.createSolanaRpc(rpcUrl ?? getRpcEndpoint(cluster));
4349
+ }
4350
+
4351
+ // src/wallets/solana/actions/transfer.ts
4352
+ async function transfer(options) {
4353
+ const { account, cluster, rpcUrl, ...rest } = options;
4354
+ const rpc = await createRpcClient(cluster, rpcUrl);
4355
+ const instructions = !options.token || options.token.toLowerCase() === "sol" ? await getNativeTransferInstructions({
4356
+ from: account.address,
4357
+ to: options.to,
4358
+ amount: options.amount
4359
+ }) : await getSplTransferInstructions({
4360
+ rpc,
4361
+ from: account.address,
4362
+ to: options.to,
4363
+ mintAddress: options.token.toLowerCase() === "usdc" ? getUsdcMintAddress(cluster) : options.token,
4364
+ amount: options.amount
4365
+ });
4366
+ return sendTransaction({
4367
+ account,
4368
+ cluster,
4369
+ instructions,
4370
+ rpcUrl,
4371
+ computeUnitLimit: rest.computeUnitLimit,
4372
+ computeUnitPrice: rest.computeUnitPrice,
4373
+ wsUrl: rest.wsUrl
4374
+ });
4375
+ }
4376
+ async function getNativeTransferInstructions({
4377
+ from,
4378
+ to,
4379
+ amount
4380
+ }) {
4381
+ let solanaKit;
4382
+ let systemProgram;
4383
+ try {
4384
+ solanaKit = await import("@solana/kit");
4385
+ } catch {
4386
+ throw new UserInputValidationError(
4387
+ "`@solana/kit` is required for transfer. Install it and try again."
4388
+ );
4389
+ }
4390
+ try {
4391
+ systemProgram = await import("@solana-program/system");
4392
+ } catch {
4393
+ throw new UserInputValidationError(
4394
+ "`@solana-program/system` is required for SOL transfers. Install it and try again."
4395
+ );
4396
+ }
4397
+ const fromAddr = solanaKit.address(from);
4398
+ const toAddr = solanaKit.address(to);
4399
+ return [
4400
+ systemProgram.getTransferSolInstruction({
4401
+ source: solanaKit.createNoopSigner(fromAddr),
4402
+ destination: toAddr,
4403
+ amount
4404
+ })
4405
+ ];
4406
+ }
4407
+ async function getSplTransferInstructions({
4408
+ rpc,
4409
+ from,
4410
+ to,
4411
+ mintAddress,
4412
+ amount
4413
+ }) {
4414
+ let solanaKit;
4415
+ let tokenProgram;
4416
+ try {
4417
+ solanaKit = await import("@solana/kit");
4418
+ } catch {
4419
+ throw new UserInputValidationError(
4420
+ "`@solana/kit` is required for transfer. Install it and try again."
4421
+ );
4422
+ }
4423
+ try {
4424
+ tokenProgram = await import("@solana-program/token");
4425
+ } catch {
4426
+ throw new UserInputValidationError(
4427
+ "`@solana-program/token` is required for SPL transfers. Install it and try again."
4428
+ );
4429
+ }
4430
+ const fromAddr = solanaKit.address(from);
4431
+ const toAddr = solanaKit.address(to);
4432
+ const mintAddr = solanaKit.address(mintAddress);
4433
+ const mintInfo = await tokenProgram.fetchMint(rpc, mintAddr).catch(() => {
4434
+ throw new UserInputValidationError(
4435
+ `Failed to fetch mint account for ${mintAddress}. Verify the mint address is correct.`
4436
+ );
4437
+ });
4438
+ const [sourceAta] = await tokenProgram.findAssociatedTokenPda({
4439
+ mint: mintAddr,
4440
+ owner: fromAddr,
4441
+ tokenProgram: tokenProgram.TOKEN_PROGRAM_ADDRESS
4442
+ });
4443
+ const [destAta] = await tokenProgram.findAssociatedTokenPda({
4444
+ mint: mintAddr,
4445
+ owner: toAddr,
4446
+ tokenProgram: tokenProgram.TOKEN_PROGRAM_ADDRESS
4447
+ });
4448
+ const sourceAcct = await tokenProgram.fetchToken(rpc, sourceAta).catch(() => {
4449
+ throw new UserInputValidationError(
4450
+ `Source account has no token account for mint ${mintAddress}`
4451
+ );
4452
+ });
4453
+ if (sourceAcct.data.amount < amount) {
4454
+ throw new UserInputValidationError(
4455
+ `Insufficient token balance: have ${sourceAcct.data.amount}, need ${amount}`
4456
+ );
4457
+ }
4458
+ const instructions = [];
4459
+ const destAccountInfo = await rpc.getAccountInfo(destAta, { encoding: "base64" }).send();
4460
+ if (!destAccountInfo.value) {
4461
+ const createDestIx = await tokenProgram.getCreateAssociatedTokenInstructionAsync({
4462
+ payer: solanaKit.createNoopSigner(fromAddr),
4463
+ owner: toAddr,
4464
+ ata: destAta,
4465
+ mint: mintAddr
4466
+ });
4467
+ instructions.push(createDestIx);
4468
+ }
4469
+ instructions.push(
4470
+ tokenProgram.getTransferCheckedInstruction({
4471
+ source: sourceAta,
4472
+ mint: mintAddr,
4473
+ destination: destAta,
4474
+ authority: solanaKit.createNoopSigner(fromAddr),
4475
+ amount,
4476
+ decimals: mintInfo.data.decimals
4477
+ })
4478
+ );
4479
+ return instructions;
4480
+ }
4481
+
4125
4482
  // src/wallets/solana/accounts/solanaAccount.ts
4126
4483
  function toSolanaAccount(data) {
4127
4484
  const { id, address } = data;
@@ -4142,6 +4499,12 @@ function toSolanaAccount(data) {
4142
4499
  transaction: parameters.transaction
4143
4500
  });
4144
4501
  return result.signedTransaction;
4502
+ },
4503
+ async transfer(options) {
4504
+ return transfer({ ...options, account });
4505
+ },
4506
+ async sendRawTransaction(options) {
4507
+ return sendRawTransaction({ ...options, account });
4145
4508
  }
4146
4509
  };
4147
4510
  return account;
@@ -4372,16 +4735,12 @@ var SolanaClient = class {
4372
4735
  return response.signature;
4373
4736
  }
4374
4737
  };
4738
+ /** Wallet type identifier used for client registration */
4375
4739
  SolanaClient.type = "solanaWallet";
4376
4740
 
4377
4741
  // src/index.ts
4378
4742
  import { ShieldAuthProvider as ShieldAuthProvider2 } from "@openfort/shield-js";
4379
4743
 
4380
- // src/wallets/evm/actions/sendTransaction.ts
4381
- import { createPublicClient, getAddress, http } from "viem";
4382
- import * as chains from "viem/chains";
4383
- import { hashAuthorization } from "viem/utils";
4384
-
4385
4744
  // src/wallets/evm/actions/updateToDelegated.ts
4386
4745
  async function update(options) {
4387
4746
  const { chainId, walletId, implementationType, accountId } = options;
@@ -4396,11 +4755,37 @@ async function update(options) {
4396
4755
  }
4397
4756
 
4398
4757
  // src/wallets/evm/actions/sendTransaction.ts
4399
- async function sendTransaction(options) {
4758
+ async function sendTransaction2(options) {
4759
+ let viem;
4760
+ let viemChains;
4761
+ let viemUtils;
4762
+ try {
4763
+ viem = await import("viem");
4764
+ } catch {
4765
+ throw new UserInputValidationError(
4766
+ "`viem` is required for sendTransaction. Install it and try again."
4767
+ );
4768
+ }
4769
+ try {
4770
+ viemChains = await import("viem/chains");
4771
+ } catch {
4772
+ throw new UserInputValidationError(
4773
+ "`viem` is required for sendTransaction. Install it and try again."
4774
+ );
4775
+ }
4776
+ try {
4777
+ viemUtils = await import("viem/utils");
4778
+ } catch {
4779
+ throw new UserInputValidationError(
4780
+ "`viem` is required for sendTransaction. Install it and try again."
4781
+ );
4782
+ }
4400
4783
  const { account, chainId, interactions, policy, rpcUrl } = options;
4401
- const transport = rpcUrl ? http(rpcUrl) : http();
4402
- const allChains = Object.values(chains);
4403
- const chain = allChains.find((c) => c.id === chainId);
4784
+ const transport = rpcUrl ? viem.http(rpcUrl) : viem.http();
4785
+ const allChains = Object.values(viemChains);
4786
+ const chain = allChains.find(
4787
+ (c) => typeof c === "object" && c !== null && "id" in c && c.id === chainId
4788
+ );
4404
4789
  if (!chain) {
4405
4790
  throw new DelegationError(
4406
4791
  `Unknown chain ID ${chainId}. Provide a custom rpcUrl for unsupported chains.`
@@ -4409,7 +4794,7 @@ async function sendTransaction(options) {
4409
4794
  let signedAuthorization;
4410
4795
  let txAccountId;
4411
4796
  const response = await getAccountsV2({
4412
- address: getAddress(account.address),
4797
+ address: viem.getAddress(account.address),
4413
4798
  accountType: "Delegated Account",
4414
4799
  chainType: "EVM",
4415
4800
  chainId
@@ -4423,11 +4808,11 @@ async function sendTransaction(options) {
4423
4808
  });
4424
4809
  txAccountId = updated.id;
4425
4810
  const implementationAddress = "0x000000009b1d0af20d8c6d0a44e162d11f9b8f00";
4426
- const publicClient = createPublicClient({ chain, transport });
4811
+ const publicClient = viem.createPublicClient({ chain, transport });
4427
4812
  const eoaNonce = await publicClient.getTransactionCount({
4428
4813
  address: account.address
4429
4814
  });
4430
- const authHash = hashAuthorization({
4815
+ const authHash = viemUtils.hashAuthorization({
4431
4816
  contractAddress: implementationAddress,
4432
4817
  chainId,
4433
4818
  nonce: eoaNonce
@@ -4454,19 +4839,6 @@ async function sendTransaction(options) {
4454
4839
  });
4455
4840
  }
4456
4841
 
4457
- // src/wallets/evm/actions/signMessage.ts
4458
- import { toHex, toPrefixedMessage as toPrefixedMessage2 } from "viem";
4459
-
4460
- // src/wallets/evm/actions/signTransaction.ts
4461
- import {
4462
- keccak256,
4463
- parseSignature as parseSignature2,
4464
- serializeTransaction as serializeTransaction2
4465
- } from "viem";
4466
-
4467
- // src/wallets/evm/actions/signTypedData.ts
4468
- import { hashTypedData as hashTypedData2 } from "viem";
4469
-
4470
4842
  // src/policies/evmSchema.ts
4471
4843
  import { z } from "zod";
4472
4844
  var EthValueOperatorEnum = z.enum(["<=", ">=", "<", ">"]);
@@ -4869,7 +5241,7 @@ var Openfort = class {
4869
5241
  /** Update EOA to delegated account */
4870
5242
  update,
4871
5243
  /** Delegate + create + sign + submit a gasless transaction in one call */
4872
- sendTransaction
5244
+ sendTransaction: sendTransaction2
4873
5245
  },
4874
5246
  /** Embedded wallet operations (User custody) */
4875
5247
  embedded: {
@@ -4898,7 +5270,13 @@ var Openfort = class {
4898
5270
  /** Import private key (with E2E encryption) */
4899
5271
  import: solanaClient.importAccount.bind(solanaClient),
4900
5272
  /** Export private key (with E2E encryption) */
4901
- export: solanaClient.exportAccount.bind(solanaClient)
5273
+ export: solanaClient.exportAccount.bind(solanaClient),
5274
+ /** Send a gasless transaction via Kora */
5275
+ sendTransaction,
5276
+ /** Send a pre-built base64 transaction via Kora gasless flow */
5277
+ sendRawTransaction,
5278
+ /** Transfer SOL or SPL tokens (high-level) */
5279
+ transfer
4902
5280
  },
4903
5281
  /** Embedded wallet operations (User custody) */
4904
5282
  embedded: {