@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.
- package/CHANGELOG.md +6 -0
- package/dist/index.d.mts +274 -84
- package/dist/index.d.ts +274 -84
- package/dist/index.js +423 -35
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +423 -45
- package/dist/index.mjs.map +1 -1
- package/examples/evm/policies/createAccountPolicy.ts +68 -0
- package/examples/evm/policies/createProjectPolicy.ts +53 -0
- package/examples/evm/policies/deletePolicy.ts +34 -0
- package/examples/evm/policies/getPolicyById.ts +34 -0
- package/examples/evm/policies/listAccountPolicies.ts +11 -0
- package/examples/evm/policies/listPolicies.ts +11 -0
- package/examples/evm/policies/listProjectPolicies.ts +11 -0
- package/examples/evm/policies/signTypedDataPolicy.ts +35 -0
- package/examples/evm/policies/updatePolicy.ts +44 -0
- package/examples/evm/policies/validation.ts +45 -0
- package/examples/evm/transactions/sendTransaction.ts +44 -0
- package/examples/package.json +13 -0
- package/examples/pnpm-lock.yaml +933 -0
- package/examples/solana/policies/createSolAllowlistPolicy.ts +27 -0
- package/examples/solana/policies/createSolMessagePolicy.ts +29 -0
- package/examples/solana/policies/createSplTokenLimitsPolicy.ts +33 -0
- package/examples/solana/transactions/sendRawTransaction.ts +23 -0
- package/examples/solana/transactions/sendTransaction.ts +37 -0
- package/examples/solana/transactions/transfer.ts +44 -0
- package/knip.json +10 -1
- package/package.json +42 -4
- package/tsconfig.json +2 -3
- package/examples/policies/createAccountPolicy.ts +0 -71
- package/examples/policies/createEvmPolicy.ts +0 -149
- package/examples/policies/createSolanaPolicy.ts +0 -176
- package/examples/policies/createTypedDataPolicy.ts +0 -159
- package/examples/policies/deletePolicy.ts +0 -34
- package/examples/policies/getPolicy.ts +0 -41
- package/examples/policies/listPolicies.ts +0 -34
- package/examples/policies/multiRulePolicy.ts +0 -133
- package/examples/policies/updatePolicy.ts +0 -77
- package/examples/policies/validatePolicy.ts +0 -176
- /package/examples/{contracts → evm/contracts}/createContract.ts +0 -0
- /package/examples/{contracts → evm/contracts}/listContracts.ts +0 -0
- /package/examples/{transactions → evm/transactionIntents}/createTransactionIntent.ts +0 -0
- /package/examples/{transactions → evm/transactionIntents}/estimateGas.ts +0 -0
- /package/examples/{transactions → evm/transactionIntents}/getTransactionIntent.ts +0 -0
- /package/examples/{transactions → evm/transactionIntents}/listTransactionIntents.ts +0 -0
package/dist/index.js
CHANGED
|
@@ -842,7 +842,7 @@ function requiresWalletAuth(requestMethod, requestPath) {
|
|
|
842
842
|
}
|
|
843
843
|
|
|
844
844
|
// src/version.ts
|
|
845
|
-
var VERSION = "0.
|
|
845
|
+
var VERSION = "0.10.0";
|
|
846
846
|
var PACKAGE = "@openfort/openfort-node";
|
|
847
847
|
|
|
848
848
|
// src/openapi-client/openfortApiClient.ts
|
|
@@ -4238,9 +4238,6 @@ var decryptExportedPrivateKey = (encryptedPrivateKeyBase64, privateKeyPem) => {
|
|
|
4238
4238
|
return decrypted.toString("hex");
|
|
4239
4239
|
};
|
|
4240
4240
|
|
|
4241
|
-
// src/wallets/evm/accounts/evmAccount.ts
|
|
4242
|
-
var import_viem = require("viem");
|
|
4243
|
-
|
|
4244
4241
|
// src/wallets/evm/actions/normalizeSignature.ts
|
|
4245
4242
|
function normalizeSignature(sig) {
|
|
4246
4243
|
const v = parseInt(sig.slice(-2), 16);
|
|
@@ -4276,29 +4273,53 @@ function toEvmAccount(data) {
|
|
|
4276
4273
|
return result.signature;
|
|
4277
4274
|
},
|
|
4278
4275
|
async signMessage(parameters) {
|
|
4276
|
+
let viem;
|
|
4277
|
+
try {
|
|
4278
|
+
viem = await import("viem");
|
|
4279
|
+
} catch {
|
|
4280
|
+
throw new UserInputValidationError(
|
|
4281
|
+
"`viem` is required for signMessage. Install it and try again."
|
|
4282
|
+
);
|
|
4283
|
+
}
|
|
4279
4284
|
const { message } = parameters;
|
|
4280
|
-
const preimage =
|
|
4285
|
+
const preimage = viem.toPrefixedMessage(message);
|
|
4281
4286
|
const result = await sign(id, { data: preimage });
|
|
4282
|
-
return result.signature;
|
|
4287
|
+
return normalizeSignature(result.signature);
|
|
4283
4288
|
},
|
|
4284
4289
|
async signTransaction(transaction) {
|
|
4285
|
-
|
|
4290
|
+
let viem;
|
|
4291
|
+
try {
|
|
4292
|
+
viem = await import("viem");
|
|
4293
|
+
} catch {
|
|
4294
|
+
throw new UserInputValidationError(
|
|
4295
|
+
"`viem` is required for signTransaction. Install it and try again."
|
|
4296
|
+
);
|
|
4297
|
+
}
|
|
4298
|
+
const serialized = viem.serializeTransaction(transaction);
|
|
4286
4299
|
const response = await sign(id, { data: serialized });
|
|
4287
|
-
const signature2 =
|
|
4288
|
-
const signedTransaction =
|
|
4300
|
+
const signature2 = viem.parseSignature(response.signature);
|
|
4301
|
+
const signedTransaction = viem.serializeTransaction(
|
|
4289
4302
|
transaction,
|
|
4290
4303
|
signature2
|
|
4291
4304
|
);
|
|
4292
4305
|
return signedTransaction;
|
|
4293
4306
|
},
|
|
4294
4307
|
async signTypedData(parameters) {
|
|
4308
|
+
let viem;
|
|
4309
|
+
try {
|
|
4310
|
+
viem = await import("viem");
|
|
4311
|
+
} catch {
|
|
4312
|
+
throw new UserInputValidationError(
|
|
4313
|
+
"`viem` is required for signTypedData. Install it and try again."
|
|
4314
|
+
);
|
|
4315
|
+
}
|
|
4295
4316
|
const {
|
|
4296
4317
|
domain = {},
|
|
4297
4318
|
message,
|
|
4298
4319
|
primaryType
|
|
4299
4320
|
} = parameters;
|
|
4300
4321
|
const types = {
|
|
4301
|
-
EIP712Domain:
|
|
4322
|
+
EIP712Domain: viem.getTypesForEIP712Domain({ domain }),
|
|
4302
4323
|
...parameters.types
|
|
4303
4324
|
};
|
|
4304
4325
|
const openApiMessage = {
|
|
@@ -4307,9 +4328,9 @@ function toEvmAccount(data) {
|
|
|
4307
4328
|
primaryType,
|
|
4308
4329
|
message
|
|
4309
4330
|
};
|
|
4310
|
-
const hash =
|
|
4331
|
+
const hash = viem.hashTypedData(openApiMessage);
|
|
4311
4332
|
const result = await sign(id, { data: hash });
|
|
4312
|
-
return result.signature;
|
|
4333
|
+
return normalizeSignature(result.signature);
|
|
4313
4334
|
}
|
|
4314
4335
|
};
|
|
4315
4336
|
return account;
|
|
@@ -4409,6 +4430,12 @@ var EvmClient = class {
|
|
|
4409
4430
|
}
|
|
4410
4431
|
throw new AccountNotFoundError();
|
|
4411
4432
|
}
|
|
4433
|
+
/**
|
|
4434
|
+
* Retrieves delegated accounts linked to an EVM address on a specific chain.
|
|
4435
|
+
*
|
|
4436
|
+
* @param options - Options containing the address and chain ID
|
|
4437
|
+
* @returns List of linked accounts
|
|
4438
|
+
*/
|
|
4412
4439
|
async getLinkedAccounts(options) {
|
|
4413
4440
|
const response = await getAccountsV2({
|
|
4414
4441
|
address: options.address,
|
|
@@ -4547,6 +4574,198 @@ EvmClient.type = "evmWallet";
|
|
|
4547
4574
|
// src/wallets/solana/solanaClient.ts
|
|
4548
4575
|
var import_bs58 = __toESM(require("bs58"));
|
|
4549
4576
|
|
|
4577
|
+
// src/wallets/solana/actions/constants.ts
|
|
4578
|
+
var USDC_MAINNET_MINT_ADDRESS = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
4579
|
+
var USDC_DEVNET_MINT_ADDRESS = "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU";
|
|
4580
|
+
var DEFAULT_COMPUTE_UNIT_LIMIT = 2e5;
|
|
4581
|
+
var DEFAULT_COMPUTE_UNIT_PRICE = 50000n;
|
|
4582
|
+
|
|
4583
|
+
// src/wallets/solana/actions/utils.ts
|
|
4584
|
+
function getUsdcMintAddress(cluster) {
|
|
4585
|
+
if (cluster === "mainnet-beta") {
|
|
4586
|
+
return USDC_MAINNET_MINT_ADDRESS;
|
|
4587
|
+
}
|
|
4588
|
+
return USDC_DEVNET_MINT_ADDRESS;
|
|
4589
|
+
}
|
|
4590
|
+
function getRpcEndpoint(cluster) {
|
|
4591
|
+
return cluster === "mainnet-beta" ? "https://api.mainnet-beta.solana.com" : "https://api.devnet.solana.com";
|
|
4592
|
+
}
|
|
4593
|
+
function getWsEndpoint(cluster) {
|
|
4594
|
+
return cluster === "mainnet-beta" ? "wss://api.mainnet-beta.solana.com" : "wss://api.devnet.solana.com";
|
|
4595
|
+
}
|
|
4596
|
+
|
|
4597
|
+
// src/wallets/solana/actions/sendTransaction.ts
|
|
4598
|
+
async function sendTransaction(options) {
|
|
4599
|
+
const {
|
|
4600
|
+
account,
|
|
4601
|
+
cluster,
|
|
4602
|
+
instructions,
|
|
4603
|
+
computeUnitLimit,
|
|
4604
|
+
computeUnitPrice,
|
|
4605
|
+
rpcUrl,
|
|
4606
|
+
wsUrl
|
|
4607
|
+
} = options;
|
|
4608
|
+
let solanaKit;
|
|
4609
|
+
let computeBudget;
|
|
4610
|
+
let transactionConfirmation;
|
|
4611
|
+
let koraModule;
|
|
4612
|
+
try {
|
|
4613
|
+
solanaKit = await import("@solana/kit");
|
|
4614
|
+
} catch {
|
|
4615
|
+
throw new UserInputValidationError(
|
|
4616
|
+
"`@solana/kit` is required for sendTransaction. Install it and try again."
|
|
4617
|
+
);
|
|
4618
|
+
}
|
|
4619
|
+
try {
|
|
4620
|
+
computeBudget = await import("@solana-program/compute-budget");
|
|
4621
|
+
} catch {
|
|
4622
|
+
throw new UserInputValidationError(
|
|
4623
|
+
"`@solana-program/compute-budget` is required for sendTransaction. Install it and try again."
|
|
4624
|
+
);
|
|
4625
|
+
}
|
|
4626
|
+
try {
|
|
4627
|
+
koraModule = await import("@solana/kora");
|
|
4628
|
+
} catch {
|
|
4629
|
+
throw new UserInputValidationError(
|
|
4630
|
+
"`@solana/kora` is required for sendTransaction. Install it and try again."
|
|
4631
|
+
);
|
|
4632
|
+
}
|
|
4633
|
+
try {
|
|
4634
|
+
transactionConfirmation = await import("@solana/transaction-confirmation");
|
|
4635
|
+
} catch {
|
|
4636
|
+
throw new UserInputValidationError(
|
|
4637
|
+
"`@solana/transaction-confirmation` is required for sendTransaction. Install it and try again."
|
|
4638
|
+
);
|
|
4639
|
+
}
|
|
4640
|
+
const userAddress = solanaKit.address(account.address);
|
|
4641
|
+
const clientConfig2 = getConfig();
|
|
4642
|
+
if (!clientConfig2?.publishableKey) {
|
|
4643
|
+
throw new MissingPublishableKeyError("sendTransaction");
|
|
4644
|
+
}
|
|
4645
|
+
const basePath = clientConfig2.basePath || "https://api.openfort.io";
|
|
4646
|
+
const client = new koraModule.KoraClient({
|
|
4647
|
+
rpcUrl: `${basePath}/rpc/solana/${cluster}`,
|
|
4648
|
+
apiKey: `Bearer ${clientConfig2.publishableKey}`
|
|
4649
|
+
});
|
|
4650
|
+
const rpc = solanaKit.createSolanaRpc(rpcUrl ?? getRpcEndpoint(cluster));
|
|
4651
|
+
const rpcSubscriptions = solanaKit.createSolanaRpcSubscriptions(
|
|
4652
|
+
wsUrl ?? getWsEndpoint(cluster)
|
|
4653
|
+
);
|
|
4654
|
+
const confirmTransaction = transactionConfirmation.createRecentSignatureConfirmationPromiseFactory({
|
|
4655
|
+
rpc,
|
|
4656
|
+
rpcSubscriptions
|
|
4657
|
+
});
|
|
4658
|
+
const { signer_address } = await client.getPayerSigner();
|
|
4659
|
+
const blockhashResponse = await client.getBlockhash();
|
|
4660
|
+
let txMsg = solanaKit.pipe(
|
|
4661
|
+
solanaKit.createTransactionMessage({ version: 0 }),
|
|
4662
|
+
(tx) => solanaKit.setTransactionMessageFeePayer(
|
|
4663
|
+
solanaKit.address(signer_address),
|
|
4664
|
+
tx
|
|
4665
|
+
),
|
|
4666
|
+
// Kora's getBlockhash does not return lastValidBlockHeight, so we use 0n.
|
|
4667
|
+
// Transaction expiry is handled by the confirmTransaction timeout instead.
|
|
4668
|
+
(tx) => solanaKit.setTransactionMessageLifetimeUsingBlockhash(
|
|
4669
|
+
{
|
|
4670
|
+
blockhash: blockhashResponse.blockhash,
|
|
4671
|
+
lastValidBlockHeight: 0n
|
|
4672
|
+
},
|
|
4673
|
+
tx
|
|
4674
|
+
),
|
|
4675
|
+
(tx) => solanaKit.appendTransactionMessageInstructions(instructions, tx),
|
|
4676
|
+
(tx) => computeBudget.updateOrAppendSetComputeUnitPriceInstruction(
|
|
4677
|
+
computeUnitPrice ?? DEFAULT_COMPUTE_UNIT_PRICE,
|
|
4678
|
+
tx
|
|
4679
|
+
),
|
|
4680
|
+
(tx) => computeBudget.updateOrAppendSetComputeUnitLimitInstruction(
|
|
4681
|
+
computeUnitLimit ?? DEFAULT_COMPUTE_UNIT_LIMIT,
|
|
4682
|
+
tx
|
|
4683
|
+
)
|
|
4684
|
+
);
|
|
4685
|
+
if (computeUnitLimit === void 0) {
|
|
4686
|
+
const estimateComputeUnitLimit = computeBudget.estimateComputeUnitLimitFactory({ rpc });
|
|
4687
|
+
try {
|
|
4688
|
+
const estimatedLimit = await estimateComputeUnitLimit(txMsg);
|
|
4689
|
+
txMsg = computeBudget.updateOrAppendSetComputeUnitLimitInstruction(
|
|
4690
|
+
estimatedLimit,
|
|
4691
|
+
txMsg
|
|
4692
|
+
);
|
|
4693
|
+
} catch {
|
|
4694
|
+
}
|
|
4695
|
+
}
|
|
4696
|
+
const compiled = solanaKit.compileTransaction(txMsg);
|
|
4697
|
+
const messageBase64 = Buffer.from(
|
|
4698
|
+
compiled.messageBytes
|
|
4699
|
+
).toString("base64");
|
|
4700
|
+
const signatureHex = await account.signTransaction({
|
|
4701
|
+
transaction: messageBase64
|
|
4702
|
+
});
|
|
4703
|
+
const sigBytes = new Uint8Array(
|
|
4704
|
+
Buffer.from(signatureHex.replace(/^0x/, ""), "hex")
|
|
4705
|
+
);
|
|
4706
|
+
const EMPTY_SIGNATURE = new Uint8Array(64);
|
|
4707
|
+
const signatures = Object.fromEntries(
|
|
4708
|
+
Object.entries(compiled.signatures).map(([addr]) => [
|
|
4709
|
+
addr,
|
|
4710
|
+
addr === userAddress ? sigBytes : EMPTY_SIGNATURE
|
|
4711
|
+
])
|
|
4712
|
+
);
|
|
4713
|
+
const signed = { ...compiled, signatures };
|
|
4714
|
+
const base64Full = solanaKit.getBase64EncodedWireTransaction(signed);
|
|
4715
|
+
const { signed_transaction } = await client.signTransaction({
|
|
4716
|
+
transaction: base64Full,
|
|
4717
|
+
signer_key: signer_address
|
|
4718
|
+
});
|
|
4719
|
+
const signature2 = await rpc.sendTransaction(
|
|
4720
|
+
signed_transaction,
|
|
4721
|
+
{ encoding: "base64" }
|
|
4722
|
+
).send();
|
|
4723
|
+
await confirmTransaction({
|
|
4724
|
+
commitment: "confirmed",
|
|
4725
|
+
signature: signature2,
|
|
4726
|
+
abortSignal: AbortSignal.timeout(6e4)
|
|
4727
|
+
});
|
|
4728
|
+
return { signature: signature2 };
|
|
4729
|
+
}
|
|
4730
|
+
|
|
4731
|
+
// src/wallets/solana/actions/sendRawTransaction.ts
|
|
4732
|
+
async function sendRawTransaction(options) {
|
|
4733
|
+
const {
|
|
4734
|
+
account,
|
|
4735
|
+
cluster,
|
|
4736
|
+
transaction,
|
|
4737
|
+
computeUnitLimit,
|
|
4738
|
+
computeUnitPrice,
|
|
4739
|
+
rpcUrl,
|
|
4740
|
+
wsUrl
|
|
4741
|
+
} = options;
|
|
4742
|
+
let solanaKit;
|
|
4743
|
+
try {
|
|
4744
|
+
solanaKit = await import("@solana/kit");
|
|
4745
|
+
} catch {
|
|
4746
|
+
throw new UserInputValidationError(
|
|
4747
|
+
"`@solana/kit` is required for sendRawTransaction. Install it and try again."
|
|
4748
|
+
);
|
|
4749
|
+
}
|
|
4750
|
+
const txBytes = new Uint8Array(Buffer.from(transaction, "base64"));
|
|
4751
|
+
const decoded = solanaKit.getTransactionDecoder().decode(txBytes);
|
|
4752
|
+
const compiledMessage = solanaKit.getCompiledTransactionMessageDecoder().decode(decoded.messageBytes);
|
|
4753
|
+
const rpc = solanaKit.createSolanaRpc(rpcUrl ?? getRpcEndpoint(cluster));
|
|
4754
|
+
const decompiled = await solanaKit.decompileTransactionMessageFetchingLookupTables(
|
|
4755
|
+
compiledMessage,
|
|
4756
|
+
rpc
|
|
4757
|
+
);
|
|
4758
|
+
return sendTransaction({
|
|
4759
|
+
account,
|
|
4760
|
+
cluster,
|
|
4761
|
+
instructions: [...decompiled.instructions],
|
|
4762
|
+
computeUnitLimit,
|
|
4763
|
+
computeUnitPrice,
|
|
4764
|
+
rpcUrl,
|
|
4765
|
+
wsUrl
|
|
4766
|
+
});
|
|
4767
|
+
}
|
|
4768
|
+
|
|
4550
4769
|
// src/wallets/solana/actions/signMessage.ts
|
|
4551
4770
|
async function signMessage(options) {
|
|
4552
4771
|
const { accountId, message } = options;
|
|
@@ -4569,6 +4788,150 @@ async function signTransaction(options) {
|
|
|
4569
4788
|
};
|
|
4570
4789
|
}
|
|
4571
4790
|
|
|
4791
|
+
// src/wallets/solana/actions/rpc.ts
|
|
4792
|
+
async function createRpcClient(cluster, rpcUrl) {
|
|
4793
|
+
let solanaKit;
|
|
4794
|
+
try {
|
|
4795
|
+
solanaKit = await import("@solana/kit");
|
|
4796
|
+
} catch {
|
|
4797
|
+
throw new UserInputValidationError(
|
|
4798
|
+
"`@solana/kit` is required. Install it and try again."
|
|
4799
|
+
);
|
|
4800
|
+
}
|
|
4801
|
+
return solanaKit.createSolanaRpc(rpcUrl ?? getRpcEndpoint(cluster));
|
|
4802
|
+
}
|
|
4803
|
+
|
|
4804
|
+
// src/wallets/solana/actions/transfer.ts
|
|
4805
|
+
async function transfer(options) {
|
|
4806
|
+
const { account, cluster, rpcUrl, ...rest } = options;
|
|
4807
|
+
const rpc = await createRpcClient(cluster, rpcUrl);
|
|
4808
|
+
const instructions = !options.token || options.token.toLowerCase() === "sol" ? await getNativeTransferInstructions({
|
|
4809
|
+
from: account.address,
|
|
4810
|
+
to: options.to,
|
|
4811
|
+
amount: options.amount
|
|
4812
|
+
}) : await getSplTransferInstructions({
|
|
4813
|
+
rpc,
|
|
4814
|
+
from: account.address,
|
|
4815
|
+
to: options.to,
|
|
4816
|
+
mintAddress: options.token.toLowerCase() === "usdc" ? getUsdcMintAddress(cluster) : options.token,
|
|
4817
|
+
amount: options.amount
|
|
4818
|
+
});
|
|
4819
|
+
return sendTransaction({
|
|
4820
|
+
account,
|
|
4821
|
+
cluster,
|
|
4822
|
+
instructions,
|
|
4823
|
+
rpcUrl,
|
|
4824
|
+
computeUnitLimit: rest.computeUnitLimit,
|
|
4825
|
+
computeUnitPrice: rest.computeUnitPrice,
|
|
4826
|
+
wsUrl: rest.wsUrl
|
|
4827
|
+
});
|
|
4828
|
+
}
|
|
4829
|
+
async function getNativeTransferInstructions({
|
|
4830
|
+
from,
|
|
4831
|
+
to,
|
|
4832
|
+
amount
|
|
4833
|
+
}) {
|
|
4834
|
+
let solanaKit;
|
|
4835
|
+
let systemProgram;
|
|
4836
|
+
try {
|
|
4837
|
+
solanaKit = await import("@solana/kit");
|
|
4838
|
+
} catch {
|
|
4839
|
+
throw new UserInputValidationError(
|
|
4840
|
+
"`@solana/kit` is required for transfer. Install it and try again."
|
|
4841
|
+
);
|
|
4842
|
+
}
|
|
4843
|
+
try {
|
|
4844
|
+
systemProgram = await import("@solana-program/system");
|
|
4845
|
+
} catch {
|
|
4846
|
+
throw new UserInputValidationError(
|
|
4847
|
+
"`@solana-program/system` is required for SOL transfers. Install it and try again."
|
|
4848
|
+
);
|
|
4849
|
+
}
|
|
4850
|
+
const fromAddr = solanaKit.address(from);
|
|
4851
|
+
const toAddr = solanaKit.address(to);
|
|
4852
|
+
return [
|
|
4853
|
+
systemProgram.getTransferSolInstruction({
|
|
4854
|
+
source: solanaKit.createNoopSigner(fromAddr),
|
|
4855
|
+
destination: toAddr,
|
|
4856
|
+
amount
|
|
4857
|
+
})
|
|
4858
|
+
];
|
|
4859
|
+
}
|
|
4860
|
+
async function getSplTransferInstructions({
|
|
4861
|
+
rpc,
|
|
4862
|
+
from,
|
|
4863
|
+
to,
|
|
4864
|
+
mintAddress,
|
|
4865
|
+
amount
|
|
4866
|
+
}) {
|
|
4867
|
+
let solanaKit;
|
|
4868
|
+
let tokenProgram;
|
|
4869
|
+
try {
|
|
4870
|
+
solanaKit = await import("@solana/kit");
|
|
4871
|
+
} catch {
|
|
4872
|
+
throw new UserInputValidationError(
|
|
4873
|
+
"`@solana/kit` is required for transfer. Install it and try again."
|
|
4874
|
+
);
|
|
4875
|
+
}
|
|
4876
|
+
try {
|
|
4877
|
+
tokenProgram = await import("@solana-program/token");
|
|
4878
|
+
} catch {
|
|
4879
|
+
throw new UserInputValidationError(
|
|
4880
|
+
"`@solana-program/token` is required for SPL transfers. Install it and try again."
|
|
4881
|
+
);
|
|
4882
|
+
}
|
|
4883
|
+
const fromAddr = solanaKit.address(from);
|
|
4884
|
+
const toAddr = solanaKit.address(to);
|
|
4885
|
+
const mintAddr = solanaKit.address(mintAddress);
|
|
4886
|
+
const mintInfo = await tokenProgram.fetchMint(rpc, mintAddr).catch(() => {
|
|
4887
|
+
throw new UserInputValidationError(
|
|
4888
|
+
`Failed to fetch mint account for ${mintAddress}. Verify the mint address is correct.`
|
|
4889
|
+
);
|
|
4890
|
+
});
|
|
4891
|
+
const [sourceAta] = await tokenProgram.findAssociatedTokenPda({
|
|
4892
|
+
mint: mintAddr,
|
|
4893
|
+
owner: fromAddr,
|
|
4894
|
+
tokenProgram: tokenProgram.TOKEN_PROGRAM_ADDRESS
|
|
4895
|
+
});
|
|
4896
|
+
const [destAta] = await tokenProgram.findAssociatedTokenPda({
|
|
4897
|
+
mint: mintAddr,
|
|
4898
|
+
owner: toAddr,
|
|
4899
|
+
tokenProgram: tokenProgram.TOKEN_PROGRAM_ADDRESS
|
|
4900
|
+
});
|
|
4901
|
+
const sourceAcct = await tokenProgram.fetchToken(rpc, sourceAta).catch(() => {
|
|
4902
|
+
throw new UserInputValidationError(
|
|
4903
|
+
`Source account has no token account for mint ${mintAddress}`
|
|
4904
|
+
);
|
|
4905
|
+
});
|
|
4906
|
+
if (sourceAcct.data.amount < amount) {
|
|
4907
|
+
throw new UserInputValidationError(
|
|
4908
|
+
`Insufficient token balance: have ${sourceAcct.data.amount}, need ${amount}`
|
|
4909
|
+
);
|
|
4910
|
+
}
|
|
4911
|
+
const instructions = [];
|
|
4912
|
+
const destAccountInfo = await rpc.getAccountInfo(destAta, { encoding: "base64" }).send();
|
|
4913
|
+
if (!destAccountInfo.value) {
|
|
4914
|
+
const createDestIx = await tokenProgram.getCreateAssociatedTokenInstructionAsync({
|
|
4915
|
+
payer: solanaKit.createNoopSigner(fromAddr),
|
|
4916
|
+
owner: toAddr,
|
|
4917
|
+
ata: destAta,
|
|
4918
|
+
mint: mintAddr
|
|
4919
|
+
});
|
|
4920
|
+
instructions.push(createDestIx);
|
|
4921
|
+
}
|
|
4922
|
+
instructions.push(
|
|
4923
|
+
tokenProgram.getTransferCheckedInstruction({
|
|
4924
|
+
source: sourceAta,
|
|
4925
|
+
mint: mintAddr,
|
|
4926
|
+
destination: destAta,
|
|
4927
|
+
authority: solanaKit.createNoopSigner(fromAddr),
|
|
4928
|
+
amount,
|
|
4929
|
+
decimals: mintInfo.data.decimals
|
|
4930
|
+
})
|
|
4931
|
+
);
|
|
4932
|
+
return instructions;
|
|
4933
|
+
}
|
|
4934
|
+
|
|
4572
4935
|
// src/wallets/solana/accounts/solanaAccount.ts
|
|
4573
4936
|
function toSolanaAccount(data) {
|
|
4574
4937
|
const { id, address } = data;
|
|
@@ -4589,6 +4952,12 @@ function toSolanaAccount(data) {
|
|
|
4589
4952
|
transaction: parameters.transaction
|
|
4590
4953
|
});
|
|
4591
4954
|
return result.signedTransaction;
|
|
4955
|
+
},
|
|
4956
|
+
async transfer(options) {
|
|
4957
|
+
return transfer({ ...options, account });
|
|
4958
|
+
},
|
|
4959
|
+
async sendRawTransaction(options) {
|
|
4960
|
+
return sendRawTransaction({ ...options, account });
|
|
4592
4961
|
}
|
|
4593
4962
|
};
|
|
4594
4963
|
return account;
|
|
@@ -4819,16 +5188,12 @@ var SolanaClient = class {
|
|
|
4819
5188
|
return response.signature;
|
|
4820
5189
|
}
|
|
4821
5190
|
};
|
|
5191
|
+
/** Wallet type identifier used for client registration */
|
|
4822
5192
|
SolanaClient.type = "solanaWallet";
|
|
4823
5193
|
|
|
4824
5194
|
// src/index.ts
|
|
4825
5195
|
var import_shield_js2 = require("@openfort/shield-js");
|
|
4826
5196
|
|
|
4827
|
-
// src/wallets/evm/actions/sendTransaction.ts
|
|
4828
|
-
var import_viem2 = require("viem");
|
|
4829
|
-
var chains = __toESM(require("viem/chains"));
|
|
4830
|
-
var import_utils = require("viem/utils");
|
|
4831
|
-
|
|
4832
5197
|
// src/wallets/evm/actions/updateToDelegated.ts
|
|
4833
5198
|
async function update(options) {
|
|
4834
5199
|
const { chainId, walletId, implementationType, accountId } = options;
|
|
@@ -4843,11 +5208,37 @@ async function update(options) {
|
|
|
4843
5208
|
}
|
|
4844
5209
|
|
|
4845
5210
|
// src/wallets/evm/actions/sendTransaction.ts
|
|
4846
|
-
async function
|
|
5211
|
+
async function sendTransaction2(options) {
|
|
5212
|
+
let viem;
|
|
5213
|
+
let viemChains;
|
|
5214
|
+
let viemUtils;
|
|
5215
|
+
try {
|
|
5216
|
+
viem = await import("viem");
|
|
5217
|
+
} catch {
|
|
5218
|
+
throw new UserInputValidationError(
|
|
5219
|
+
"`viem` is required for sendTransaction. Install it and try again."
|
|
5220
|
+
);
|
|
5221
|
+
}
|
|
5222
|
+
try {
|
|
5223
|
+
viemChains = await import("viem/chains");
|
|
5224
|
+
} catch {
|
|
5225
|
+
throw new UserInputValidationError(
|
|
5226
|
+
"`viem` is required for sendTransaction. Install it and try again."
|
|
5227
|
+
);
|
|
5228
|
+
}
|
|
5229
|
+
try {
|
|
5230
|
+
viemUtils = await import("viem/utils");
|
|
5231
|
+
} catch {
|
|
5232
|
+
throw new UserInputValidationError(
|
|
5233
|
+
"`viem` is required for sendTransaction. Install it and try again."
|
|
5234
|
+
);
|
|
5235
|
+
}
|
|
4847
5236
|
const { account, chainId, interactions, policy, rpcUrl } = options;
|
|
4848
|
-
const transport = rpcUrl ?
|
|
4849
|
-
const allChains = Object.values(
|
|
4850
|
-
const chain = allChains.find(
|
|
5237
|
+
const transport = rpcUrl ? viem.http(rpcUrl) : viem.http();
|
|
5238
|
+
const allChains = Object.values(viemChains);
|
|
5239
|
+
const chain = allChains.find(
|
|
5240
|
+
(c) => typeof c === "object" && c !== null && "id" in c && c.id === chainId
|
|
5241
|
+
);
|
|
4851
5242
|
if (!chain) {
|
|
4852
5243
|
throw new DelegationError(
|
|
4853
5244
|
`Unknown chain ID ${chainId}. Provide a custom rpcUrl for unsupported chains.`
|
|
@@ -4856,7 +5247,7 @@ async function sendTransaction(options) {
|
|
|
4856
5247
|
let signedAuthorization;
|
|
4857
5248
|
let txAccountId;
|
|
4858
5249
|
const response = await getAccountsV2({
|
|
4859
|
-
address:
|
|
5250
|
+
address: viem.getAddress(account.address),
|
|
4860
5251
|
accountType: "Delegated Account",
|
|
4861
5252
|
chainType: "EVM",
|
|
4862
5253
|
chainId
|
|
@@ -4870,11 +5261,11 @@ async function sendTransaction(options) {
|
|
|
4870
5261
|
});
|
|
4871
5262
|
txAccountId = updated.id;
|
|
4872
5263
|
const implementationAddress = "0x000000009b1d0af20d8c6d0a44e162d11f9b8f00";
|
|
4873
|
-
const publicClient =
|
|
5264
|
+
const publicClient = viem.createPublicClient({ chain, transport });
|
|
4874
5265
|
const eoaNonce = await publicClient.getTransactionCount({
|
|
4875
5266
|
address: account.address
|
|
4876
5267
|
});
|
|
4877
|
-
const authHash =
|
|
5268
|
+
const authHash = viemUtils.hashAuthorization({
|
|
4878
5269
|
contractAddress: implementationAddress,
|
|
4879
5270
|
chainId,
|
|
4880
5271
|
nonce: eoaNonce
|
|
@@ -4901,15 +5292,6 @@ async function sendTransaction(options) {
|
|
|
4901
5292
|
});
|
|
4902
5293
|
}
|
|
4903
5294
|
|
|
4904
|
-
// src/wallets/evm/actions/signMessage.ts
|
|
4905
|
-
var import_viem3 = require("viem");
|
|
4906
|
-
|
|
4907
|
-
// src/wallets/evm/actions/signTransaction.ts
|
|
4908
|
-
var import_viem4 = require("viem");
|
|
4909
|
-
|
|
4910
|
-
// src/wallets/evm/actions/signTypedData.ts
|
|
4911
|
-
var import_viem5 = require("viem");
|
|
4912
|
-
|
|
4913
5295
|
// src/policies/evmSchema.ts
|
|
4914
5296
|
var import_zod = require("zod");
|
|
4915
5297
|
var EthValueOperatorEnum = import_zod.z.enum(["<=", ">=", "<", ">"]);
|
|
@@ -5312,7 +5694,7 @@ var Openfort = class {
|
|
|
5312
5694
|
/** Update EOA to delegated account */
|
|
5313
5695
|
update,
|
|
5314
5696
|
/** Delegate + create + sign + submit a gasless transaction in one call */
|
|
5315
|
-
sendTransaction
|
|
5697
|
+
sendTransaction: sendTransaction2
|
|
5316
5698
|
},
|
|
5317
5699
|
/** Embedded wallet operations (User custody) */
|
|
5318
5700
|
embedded: {
|
|
@@ -5341,7 +5723,13 @@ var Openfort = class {
|
|
|
5341
5723
|
/** Import private key (with E2E encryption) */
|
|
5342
5724
|
import: solanaClient.importAccount.bind(solanaClient),
|
|
5343
5725
|
/** Export private key (with E2E encryption) */
|
|
5344
|
-
export: solanaClient.exportAccount.bind(solanaClient)
|
|
5726
|
+
export: solanaClient.exportAccount.bind(solanaClient),
|
|
5727
|
+
/** Send a gasless transaction via Kora */
|
|
5728
|
+
sendTransaction,
|
|
5729
|
+
/** Send a pre-built base64 transaction via Kora gasless flow */
|
|
5730
|
+
sendRawTransaction,
|
|
5731
|
+
/** Transfer SOL or SPL tokens (high-level) */
|
|
5732
|
+
transfer
|
|
5345
5733
|
},
|
|
5346
5734
|
/** Embedded wallet operations (User custody) */
|
|
5347
5735
|
embedded: {
|