emblem-vault-ai-signers 0.1.8-experimental.1 → 0.2.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/README.md +118 -11
- package/dist/ethers.d.ts +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/solana.d.ts +26 -4
- package/dist/solana.js +137 -8
- package/package.json +16 -6
package/README.md
CHANGED
|
@@ -7,8 +7,8 @@ Remote signer adapters for Emblem Vault that plug into popular Ethereum librarie
|
|
|
7
7
|
- Implements `initialize()`, `getVaultId()`, `setChainId()`, `getChainId()`
|
|
8
8
|
- Adds `signAndBroadcast(tx, waitForReceipt?)` helper (optional)
|
|
9
9
|
- `toWeb3Adapter()` – returns a minimal Web3-style signer adapter (EVM)
|
|
10
|
-
- `toSolanaWeb3Signer()` –
|
|
11
|
-
- `toSolanaKitSigner()` –
|
|
10
|
+
- `toSolanaWeb3Signer()` – creates a @solana/web3.js compatible signer
|
|
11
|
+
- `toSolanaKitSigner()` – creates a Solana Kit compatible signer
|
|
12
12
|
|
|
13
13
|
> Note: The ethers adapter targets ethers v6.
|
|
14
14
|
|
|
@@ -21,6 +21,9 @@ npm install emblem-vault-ai-signers
|
|
|
21
21
|
# and bring your own peers
|
|
22
22
|
npm install ethers viem
|
|
23
23
|
|
|
24
|
+
# Optional: for Solana support
|
|
25
|
+
npm install @solana/web3.js
|
|
26
|
+
|
|
24
27
|
# Optional: for SDK integration
|
|
25
28
|
npm install emblem-auth-sdk
|
|
26
29
|
```
|
|
@@ -66,11 +69,44 @@ const txHash = await wallet.signAndBroadcast({ to: "0x...", value: 1n }, true);
|
|
|
66
69
|
const web3Adapter = await client.toWeb3Adapter();
|
|
67
70
|
await web3Adapter.signMessage("hello");
|
|
68
71
|
|
|
69
|
-
// Solana
|
|
72
|
+
// Solana (@solana/web3.js compatible)
|
|
70
73
|
const solWeb3 = await client.toSolanaWeb3Signer();
|
|
71
|
-
console.log(solWeb3.publicKey);
|
|
74
|
+
console.log(solWeb3.publicKey); // base58 Solana address
|
|
75
|
+
|
|
76
|
+
// Sign a message
|
|
77
|
+
const signature = await solWeb3.signMessage("Hello Solana");
|
|
78
|
+
|
|
79
|
+
// Sign a transaction
|
|
80
|
+
import { VersionedTransaction, TransactionMessage, SystemProgram, PublicKey } from "@solana/web3.js";
|
|
81
|
+
|
|
82
|
+
const fromPubkey = new PublicKey(solWeb3.publicKey);
|
|
83
|
+
const toPubkey = new PublicKey("...");
|
|
84
|
+
|
|
85
|
+
const messageV0 = new TransactionMessage({
|
|
86
|
+
payerKey: fromPubkey,
|
|
87
|
+
recentBlockhash: "...", // fetch from connection
|
|
88
|
+
instructions: [
|
|
89
|
+
SystemProgram.transfer({
|
|
90
|
+
fromPubkey,
|
|
91
|
+
toPubkey,
|
|
92
|
+
lamports: 1000000,
|
|
93
|
+
}),
|
|
94
|
+
],
|
|
95
|
+
}).compileToV0Message();
|
|
96
|
+
|
|
97
|
+
const transaction = new VersionedTransaction(messageV0);
|
|
98
|
+
const signedTx = await solWeb3.signTransaction(transaction);
|
|
99
|
+
|
|
100
|
+
// Sign and broadcast
|
|
101
|
+
const txSignature = await solWeb3.signAndBroadcast(transaction, true);
|
|
102
|
+
|
|
103
|
+
// Utility methods
|
|
104
|
+
const vaultId = solWeb3.getVaultId();
|
|
105
|
+
const canSign = solWeb3.canSign(solWeb3.publicKey); // true
|
|
106
|
+
|
|
107
|
+
// Solana Kit compatible signer
|
|
72
108
|
const solKit = await client.toSolanaKitSigner();
|
|
73
|
-
|
|
109
|
+
// Same interface as solWeb3
|
|
74
110
|
```
|
|
75
111
|
|
|
76
112
|
## Authentication
|
|
@@ -305,13 +341,43 @@ const provider = new JsonRpcProvider(process.env.RPC_URL!);
|
|
|
305
341
|
await provider.broadcastTransaction(rawTransaction);
|
|
306
342
|
```
|
|
307
343
|
|
|
308
|
-
### Solana (
|
|
344
|
+
### Solana (@solana/web3.js)
|
|
309
345
|
|
|
310
|
-
|
|
346
|
+
Full Solana signing support with message and transaction signing via remote vault.
|
|
311
347
|
|
|
312
348
|
```ts
|
|
313
|
-
const
|
|
314
|
-
|
|
349
|
+
const client = createEmblemClient({ apiKey: process.env.EMBLEM_API_KEY! });
|
|
350
|
+
|
|
351
|
+
// Create Solana signer
|
|
352
|
+
const solSigner = await client.toSolanaWeb3Signer();
|
|
353
|
+
console.log(solSigner.publicKey); // Base58 Solana address
|
|
354
|
+
|
|
355
|
+
// Sign messages
|
|
356
|
+
const message = "Hello Solana";
|
|
357
|
+
const signature = await solSigner.signMessage(message);
|
|
358
|
+
console.log(signature); // Uint8Array signature
|
|
359
|
+
|
|
360
|
+
// Sign transactions
|
|
361
|
+
const transaction = new Transaction()
|
|
362
|
+
.add(SystemProgram.transfer({
|
|
363
|
+
fromPubkey: new PublicKey(solSigner.publicKey),
|
|
364
|
+
toPubkey: new PublicKey("recipient-address"),
|
|
365
|
+
lamports: 1000000 // 0.001 SOL
|
|
366
|
+
}));
|
|
367
|
+
|
|
368
|
+
// Option 1: Sign only
|
|
369
|
+
const signedTx = await solSigner.signTransaction(transaction);
|
|
370
|
+
|
|
371
|
+
// Option 2: Sign and broadcast
|
|
372
|
+
const txSignature = await solSigner.signAndBroadcast(transaction, true);
|
|
373
|
+
console.log("Transaction signature:", txSignature);
|
|
374
|
+
|
|
375
|
+
// Utility methods
|
|
376
|
+
console.log("Vault ID:", solSigner.getVaultId());
|
|
377
|
+
console.log("Can sign for this key?", solSigner.canSign(solSigner.publicKey));
|
|
378
|
+
|
|
379
|
+
// Both @solana/web3.js and Solana Kit compatible
|
|
380
|
+
const solKit = await client.toSolanaKitSigner(); // Same interface
|
|
315
381
|
```
|
|
316
382
|
|
|
317
383
|
## API
|
|
@@ -332,8 +398,8 @@ createEmblemClient(config): EmblemVaultClient
|
|
|
332
398
|
EmblemVaultClient#toViemAccount(): Promise<Account>
|
|
333
399
|
EmblemVaultClient#toEthersWallet(provider?): Promise<Signer>
|
|
334
400
|
EmblemVaultClient#toWeb3Adapter(): Promise<{ address, signMessage, signTypedData, signTransaction }>
|
|
335
|
-
EmblemVaultClient#toSolanaWeb3Signer(): Promise<{ publicKey }>
|
|
336
|
-
EmblemVaultClient#toSolanaKitSigner(): Promise<{ publicKey }>
|
|
401
|
+
EmblemVaultClient#toSolanaWeb3Signer(): Promise<{ publicKey, signMessage, signTransaction, signAndBroadcast, getVaultId, canSign, signAllTransactions }>
|
|
402
|
+
EmblemVaultClient#toSolanaKitSigner(): Promise<{ publicKey, signMessage, signTransaction, signAndBroadcast, getVaultId, canSign, signAllTransactions }>
|
|
337
403
|
|
|
338
404
|
Ethers wallet (v6) adds:
|
|
339
405
|
- initialize(): Promise<void>
|
|
@@ -345,10 +411,15 @@ Ethers wallet (v6) adds:
|
|
|
345
411
|
|
|
346
412
|
Adapters POST to the Emblem API endpoints:
|
|
347
413
|
|
|
414
|
+
**EVM:**
|
|
348
415
|
- `POST /sign-eth-message` – `{ vaultId, message }`
|
|
349
416
|
- `POST /sign-typed-message` – `{ vaultId, domain, types, message }`
|
|
350
417
|
- `POST /sign-eth-tx` – `{ vaultId, transaction }` (expects ethers-serializable fields)
|
|
351
418
|
|
|
419
|
+
**Solana:**
|
|
420
|
+
- `POST /sign-solana-message` – `{ vaultId, message }` (base64 encoded)
|
|
421
|
+
- `POST /sign-solana-transaction` – `{ vaultId, transactionToSign, broadcast, versionedTransaction }` (base64 serialized)
|
|
422
|
+
|
|
352
423
|
On first use, both adapters query `POST /vault/info` with authentication headers to obtain:
|
|
353
424
|
|
|
354
425
|
- Vault ID
|
|
@@ -357,6 +428,42 @@ On first use, both adapters query `POST /vault/info` with authentication headers
|
|
|
357
428
|
|
|
358
429
|
Transactions are normalized to hex/number-like fields before submission.
|
|
359
430
|
|
|
431
|
+
### Solana
|
|
432
|
+
|
|
433
|
+
Old (local keypair):
|
|
434
|
+
```ts
|
|
435
|
+
import { Keypair, Transaction } from "@solana/web3.js";
|
|
436
|
+
|
|
437
|
+
const keypair = Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY!));
|
|
438
|
+
const transaction = new Transaction().add(...);
|
|
439
|
+
transaction.sign(keypair);
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
New (Emblem remote signer):
|
|
443
|
+
```ts
|
|
444
|
+
import { createEmblemClient } from "emblem-vault-ai-signers";
|
|
445
|
+
import { VersionedTransaction, TransactionMessage } from "@solana/web3.js";
|
|
446
|
+
|
|
447
|
+
const client = createEmblemClient({ apiKey: process.env.EMBLEM_API_KEY! });
|
|
448
|
+
const signer = await client.toSolanaWeb3Signer();
|
|
449
|
+
|
|
450
|
+
// Sign messages
|
|
451
|
+
const msgSignature = await signer.signMessage("Hello Solana");
|
|
452
|
+
|
|
453
|
+
// Sign versioned transactions
|
|
454
|
+
const messageV0 = new TransactionMessage({
|
|
455
|
+
payerKey: new PublicKey(signer.publicKey),
|
|
456
|
+
recentBlockhash: "...",
|
|
457
|
+
instructions: [...]
|
|
458
|
+
}).compileToV0Message();
|
|
459
|
+
|
|
460
|
+
const transaction = new VersionedTransaction(messageV0);
|
|
461
|
+
const signedTx = await signer.signTransaction(transaction);
|
|
462
|
+
|
|
463
|
+
// Sign and broadcast
|
|
464
|
+
const txSig = await signer.signAndBroadcast(transaction, true);
|
|
465
|
+
```
|
|
466
|
+
|
|
360
467
|
## Security Considerations
|
|
361
468
|
|
|
362
469
|
### Client-Side Usage
|
package/dist/ethers.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { EmblemRemoteConfig, VaultInfo } from "./types.js";
|
|
2
2
|
import { AbstractSigner } from "ethers";
|
|
3
|
-
import type {
|
|
3
|
+
import type { AbstractProvider, TransactionLike, TransactionRequest, TransactionResponse, TypedDataDomain, TypedDataField } from "ethers";
|
|
4
4
|
export declare class EmblemEthersWallet extends AbstractSigner {
|
|
5
5
|
private readonly _config;
|
|
6
6
|
private _address;
|
|
7
7
|
private _vaultId;
|
|
8
8
|
private _chainId;
|
|
9
9
|
private _initPromise?;
|
|
10
|
-
constructor(config: EmblemRemoteConfig, provider?:
|
|
10
|
+
constructor(config: EmblemRemoteConfig, provider?: AbstractProvider | null, seed?: {
|
|
11
11
|
address?: `0x${string}`;
|
|
12
12
|
vaultId?: string;
|
|
13
13
|
chainId?: number;
|
|
@@ -17,7 +17,7 @@ export declare class EmblemEthersWallet extends AbstractSigner {
|
|
|
17
17
|
getVaultId(): string;
|
|
18
18
|
setChainId(chainId: number): void;
|
|
19
19
|
getChainId(): number;
|
|
20
|
-
connect(provider:
|
|
20
|
+
connect(provider: AbstractProvider): EmblemEthersWallet;
|
|
21
21
|
signMessage(message: string | Uint8Array): Promise<string>;
|
|
22
22
|
signTypedData(domain: TypedDataDomain, types: Record<string, Array<TypedDataField>>, value: Record<string, any>): Promise<string>;
|
|
23
23
|
_signTypedData(domain: TypedDataDomain, types: Record<string, Array<TypedDataField>>, value: Record<string, any>): Promise<string>;
|
|
@@ -26,4 +26,4 @@ export declare class EmblemEthersWallet extends AbstractSigner {
|
|
|
26
26
|
populateTransaction(transaction: TransactionRequest): Promise<TransactionLike<string>>;
|
|
27
27
|
signAndBroadcast(transaction: TransactionRequest, waitForReceipt?: boolean): Promise<string>;
|
|
28
28
|
}
|
|
29
|
-
export declare function toEthersWallet(config: EmblemRemoteConfig, provider?:
|
|
29
|
+
export declare function toEthersWallet(config: EmblemRemoteConfig, provider?: AbstractProvider | null, infoOverride?: VaultInfo): Promise<EmblemEthersWallet>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AbstractProvider } from "ethers";
|
|
2
2
|
import type { EmblemRemoteConfig } from "./types.js";
|
|
3
3
|
export type { EmblemRemoteConfig, Hex, VaultInfo } from "./types.js";
|
|
4
4
|
export type { EmblemSecurityConfig } from "./validation.js";
|
|
@@ -31,7 +31,7 @@ export declare class EmblemVaultClient {
|
|
|
31
31
|
source: string;
|
|
32
32
|
type: "local";
|
|
33
33
|
}>;
|
|
34
|
-
toEthersWallet(provider?:
|
|
34
|
+
toEthersWallet(provider?: AbstractProvider | null): Promise<EmblemEthersWallet>;
|
|
35
35
|
toSolanaWeb3Signer(): Promise<EmblemSolanaSigner>;
|
|
36
36
|
toSolanaKitSigner(): Promise<EmblemSolanaSigner>;
|
|
37
37
|
toWeb3Adapter(): Promise<EmblemWeb3Adapter>;
|
package/dist/solana.d.ts
CHANGED
|
@@ -1,9 +1,31 @@
|
|
|
1
1
|
import type { EmblemRemoteConfig, VaultInfo } from "./types.js";
|
|
2
|
-
export
|
|
2
|
+
export interface SolanaSignerInterface {
|
|
3
|
+
publicKey: string;
|
|
4
|
+
signMessage(message: Uint8Array | string): Promise<Uint8Array>;
|
|
5
|
+
signTransaction(transaction: any): Promise<any>;
|
|
6
|
+
}
|
|
7
|
+
export interface SolanaKitSignerInterface {
|
|
8
|
+
publicKey: string;
|
|
9
|
+
signMessage(message: Uint8Array | string): Promise<Uint8Array>;
|
|
10
|
+
signTransaction(transaction: any): Promise<any>;
|
|
11
|
+
}
|
|
12
|
+
export declare class EmblemSolanaSigner implements SolanaSignerInterface, SolanaKitSignerInterface {
|
|
3
13
|
readonly publicKey: string;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
14
|
+
private readonly config;
|
|
15
|
+
private readonly vaultId;
|
|
16
|
+
constructor(config: EmblemRemoteConfig, vaultInfo: VaultInfo);
|
|
17
|
+
signMessage(message: Uint8Array | string): Promise<Uint8Array>;
|
|
18
|
+
signTransaction(transaction: any): Promise<any>;
|
|
19
|
+
private serializeTransaction;
|
|
20
|
+
private deserializeTransaction;
|
|
21
|
+
/** Get the vault ID for this signer */
|
|
22
|
+
getVaultId(): string;
|
|
23
|
+
/** Sign multiple transactions in batch */
|
|
24
|
+
signAllTransactions(transactions: any[]): Promise<any[]>;
|
|
25
|
+
/** Check if this signer can sign for a given public key */
|
|
26
|
+
canSign(publicKey: string): boolean;
|
|
27
|
+
/** Sign and optionally broadcast a transaction */
|
|
28
|
+
signAndBroadcast(transaction: any, broadcast?: boolean): Promise<string>;
|
|
7
29
|
}
|
|
8
30
|
export declare function toSolanaWeb3Signer(config: EmblemRemoteConfig, infoOverride?: VaultInfo): Promise<EmblemSolanaSigner>;
|
|
9
31
|
export declare function toSolanaKitSigner(config: EmblemRemoteConfig, infoOverride?: VaultInfo): Promise<EmblemSolanaSigner>;
|
package/dist/solana.js
CHANGED
|
@@ -1,20 +1,149 @@
|
|
|
1
|
+
import { emblemPost } from "./http.js";
|
|
1
2
|
import { fetchVaultInfo } from "./vault.js";
|
|
2
3
|
export class EmblemSolanaSigner {
|
|
3
|
-
constructor(
|
|
4
|
-
this.publicKey =
|
|
4
|
+
constructor(config, vaultInfo) {
|
|
5
|
+
this.publicKey = vaultInfo.address;
|
|
6
|
+
this.config = config;
|
|
7
|
+
this.vaultId = vaultInfo.vaultId;
|
|
5
8
|
}
|
|
6
|
-
async signMessage(
|
|
7
|
-
|
|
9
|
+
async signMessage(message) {
|
|
10
|
+
// Convert message to bytes if it's a string
|
|
11
|
+
const messageBytes = typeof message === 'string'
|
|
12
|
+
? new TextEncoder().encode(message)
|
|
13
|
+
: message;
|
|
14
|
+
// Convert to base64 for API transmission
|
|
15
|
+
const messageBase64 = btoa(String.fromCharCode(...messageBytes));
|
|
16
|
+
const response = await emblemPost("/sign-solana-message", { vaultId: this.vaultId, message: messageBase64 }, this.config);
|
|
17
|
+
// The server returns a signature - could be base64, base58, or hex
|
|
18
|
+
// Let's check what format we're getting and handle accordingly
|
|
19
|
+
// Try to decode as base58 first (Solana standard)
|
|
20
|
+
try {
|
|
21
|
+
// Use @solana/web3.js bs58 decoder if available, otherwise fallback
|
|
22
|
+
if (typeof window !== 'undefined' && window.bs58) {
|
|
23
|
+
return window.bs58.decode(response.signature);
|
|
24
|
+
}
|
|
25
|
+
// For Node.js environments or if bs58 is not globally available
|
|
26
|
+
// The signature might be base64 encoded
|
|
27
|
+
const signatureBytes = Uint8Array.from(atob(response.signature), c => c.charCodeAt(0));
|
|
28
|
+
return signatureBytes;
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
// If base64 decode fails, try treating as hex
|
|
32
|
+
if (response.signature.startsWith('0x')) {
|
|
33
|
+
const hex = response.signature.slice(2);
|
|
34
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
35
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
36
|
+
bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
|
|
37
|
+
}
|
|
38
|
+
return bytes;
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`Unable to decode signature format: ${e}`);
|
|
41
|
+
}
|
|
8
42
|
}
|
|
9
|
-
async signTransaction(
|
|
10
|
-
|
|
43
|
+
async signTransaction(transaction) {
|
|
44
|
+
// Serialize transaction for API transmission
|
|
45
|
+
const serializedTransaction = this.serializeTransaction(transaction);
|
|
46
|
+
const response = await emblemPost("/sign-solana-transaction", {
|
|
47
|
+
vaultId: this.vaultId,
|
|
48
|
+
transactionToSign: serializedTransaction, // Pass the base64 string directly
|
|
49
|
+
broadcast: false, // Don't broadcast, just sign
|
|
50
|
+
versionedTransaction: true // Match API test format
|
|
51
|
+
}, this.config);
|
|
52
|
+
// Parse the signed transaction response - handle both response formats
|
|
53
|
+
const signedTxData = response.serializedSignedTransaction || response.signedTransaction;
|
|
54
|
+
if (!signedTxData) {
|
|
55
|
+
throw new Error('No signed transaction data received from server');
|
|
56
|
+
}
|
|
57
|
+
return this.deserializeTransaction(signedTxData);
|
|
58
|
+
}
|
|
59
|
+
serializeTransaction(tx) {
|
|
60
|
+
// Handle different transaction formats from @solana/web3.js
|
|
61
|
+
if (tx && typeof tx === 'object') {
|
|
62
|
+
// For VersionedTransaction or Transaction objects
|
|
63
|
+
if (tx.serialize) {
|
|
64
|
+
// Server expects just the base64 string, not an object
|
|
65
|
+
const serialized = tx.serialize();
|
|
66
|
+
const base64 = btoa(String.fromCharCode(...serialized));
|
|
67
|
+
return base64;
|
|
68
|
+
}
|
|
69
|
+
// For transaction objects with instructions
|
|
70
|
+
if (tx.instructions || tx.recentBlockhash) {
|
|
71
|
+
throw new Error('Cannot serialize unsigned transaction objects. Please use VersionedTransaction.');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Fallback: assume it's already a string
|
|
75
|
+
return tx;
|
|
76
|
+
}
|
|
77
|
+
deserializeTransaction(signedTxData) {
|
|
78
|
+
// If it's already an object (shouldn't happen based on type), handle it
|
|
79
|
+
if (typeof signedTxData === 'object' && signedTxData.serializedSignedTransaction) {
|
|
80
|
+
signedTxData = signedTxData.serializedSignedTransaction;
|
|
81
|
+
}
|
|
82
|
+
// If it's a string, decode from base64
|
|
83
|
+
if (typeof signedTxData === 'string') {
|
|
84
|
+
try {
|
|
85
|
+
// The server returns base64, so decode it
|
|
86
|
+
const decoded = atob(signedTxData);
|
|
87
|
+
return new Uint8Array(decoded.split('').map(c => c.charCodeAt(0)));
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
console.error('Failed to decode transaction:', e);
|
|
91
|
+
throw new Error(`Unable to deserialize transaction response: ${e}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// If it's already a Uint8Array or other type, return as-is
|
|
95
|
+
return signedTxData;
|
|
96
|
+
}
|
|
97
|
+
// Additional utility methods for @solana/web3.js compatibility
|
|
98
|
+
/** Get the vault ID for this signer */
|
|
99
|
+
getVaultId() {
|
|
100
|
+
return this.vaultId;
|
|
101
|
+
}
|
|
102
|
+
/** Sign multiple transactions in batch */
|
|
103
|
+
async signAllTransactions(transactions) {
|
|
104
|
+
// Sign each transaction individually for now
|
|
105
|
+
// Could be optimized with a batch API endpoint in the future
|
|
106
|
+
const results = [];
|
|
107
|
+
for (const tx of transactions) {
|
|
108
|
+
results.push(await this.signTransaction(tx));
|
|
109
|
+
}
|
|
110
|
+
return results;
|
|
111
|
+
}
|
|
112
|
+
/** Check if this signer can sign for a given public key */
|
|
113
|
+
canSign(publicKey) {
|
|
114
|
+
return publicKey === this.publicKey;
|
|
115
|
+
}
|
|
116
|
+
/** Sign and optionally broadcast a transaction */
|
|
117
|
+
async signAndBroadcast(transaction, broadcast = true) {
|
|
118
|
+
// Serialize transaction for API transmission
|
|
119
|
+
const serializedTransaction = this.serializeTransaction(transaction);
|
|
120
|
+
const response = await emblemPost("/sign-solana-transaction", {
|
|
121
|
+
vaultId: this.vaultId,
|
|
122
|
+
transactionToSign: serializedTransaction, // Pass the base64 string directly
|
|
123
|
+
broadcast: broadcast,
|
|
124
|
+
versionedTransaction: true // Match API test format
|
|
125
|
+
}, this.config);
|
|
126
|
+
if (broadcast) {
|
|
127
|
+
// Return the transaction signature
|
|
128
|
+
if (!response.transactionSignature) {
|
|
129
|
+
throw new Error('No transaction signature received from broadcast');
|
|
130
|
+
}
|
|
131
|
+
return response.transactionSignature;
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
// Return the signed transaction data
|
|
135
|
+
if (!response.serializedSignedTransaction) {
|
|
136
|
+
throw new Error('No signed transaction data received from server');
|
|
137
|
+
}
|
|
138
|
+
return response.serializedSignedTransaction;
|
|
139
|
+
}
|
|
11
140
|
}
|
|
12
141
|
}
|
|
13
142
|
export async function toSolanaWeb3Signer(config, infoOverride) {
|
|
14
143
|
const info = infoOverride ?? (await fetchVaultInfo(config));
|
|
15
|
-
return new EmblemSolanaSigner(info
|
|
144
|
+
return new EmblemSolanaSigner(config, info);
|
|
16
145
|
}
|
|
17
146
|
export async function toSolanaKitSigner(config, infoOverride) {
|
|
18
147
|
const info = infoOverride ?? (await fetchVaultInfo(config));
|
|
19
|
-
return new EmblemSolanaSigner(info
|
|
148
|
+
return new EmblemSolanaSigner(config, info);
|
|
20
149
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "emblem-vault-ai-signers",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Emblem Vault remote signer adapters for viem and ethers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,19 +33,29 @@
|
|
|
33
33
|
"vault",
|
|
34
34
|
"signer",
|
|
35
35
|
"ethers",
|
|
36
|
-
"viem"
|
|
36
|
+
"viem",
|
|
37
|
+
"solana"
|
|
37
38
|
],
|
|
38
39
|
"author": "",
|
|
39
40
|
"license": "MIT",
|
|
40
41
|
"peerDependencies": {
|
|
41
42
|
"ethers": "^6.10.0",
|
|
42
|
-
"viem": "^2.0.0"
|
|
43
|
+
"viem": "^2.0.0",
|
|
44
|
+
"@solana/web3.js": "^1.95.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependenciesMeta": {
|
|
47
|
+
"ethers": { "optional": true },
|
|
48
|
+
"viem": { "optional": true },
|
|
49
|
+
"@solana/web3.js": { "optional": true }
|
|
43
50
|
},
|
|
44
51
|
"devDependencies": {
|
|
45
|
-
"
|
|
46
|
-
"
|
|
52
|
+
"@solana/web3.js": "^1.95.0",
|
|
53
|
+
"bs58": "^6.0.0",
|
|
47
54
|
"dotenv": "^16.4.5",
|
|
48
55
|
"ethers": "^6.10.0",
|
|
49
|
-
"
|
|
56
|
+
"tweetnacl": "^1.0.3",
|
|
57
|
+
"typescript": "^5.3.3",
|
|
58
|
+
"viem": "^2.0.0",
|
|
59
|
+
"vitest": "^1.6.0"
|
|
50
60
|
}
|
|
51
61
|
}
|