@bitgo/wasm-solana 1.5.0 → 2.0.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.
@@ -0,0 +1,197 @@
1
+ /**
2
+ * High-level intent-based transaction building.
3
+ *
4
+ * This module provides `buildFromIntent()` which accepts BitGo intent objects
5
+ * directly and builds Solana transactions without requiring the caller to
6
+ * construct low-level instructions.
7
+ *
8
+ * The intent → transaction mapping happens entirely in Rust/WASM for simplicity.
9
+ *
10
+ * Usage:
11
+ * ```typescript
12
+ * import { buildFromIntent } from '@bitgo/wasm-solana';
13
+ *
14
+ * const result = buildFromIntent(intent, {
15
+ * feePayer: walletRootAddress,
16
+ * nonce: { type: 'blockhash', value: recentBlockhash },
17
+ * });
18
+ *
19
+ * // result.transaction - Transaction object
20
+ * // result.generatedKeypairs - any keypairs generated (e.g., stake accounts)
21
+ * ```
22
+ */
23
+ import { Transaction } from "./transaction.js";
24
+ /** Nonce source - blockhash or durable nonce */
25
+ export type NonceSource = BlockhashNonce | DurableNonce;
26
+ export interface BlockhashNonce {
27
+ type: "blockhash";
28
+ value: string;
29
+ }
30
+ export interface DurableNonce {
31
+ type: "durable";
32
+ address: string;
33
+ authority: string;
34
+ value: string;
35
+ }
36
+ /** Parameters for building a transaction from intent */
37
+ export interface BuildFromIntentParams {
38
+ /** Fee payer address (wallet root) */
39
+ feePayer: string;
40
+ /** Nonce source - blockhash or durable nonce */
41
+ nonce: NonceSource;
42
+ }
43
+ /** A keypair generated during transaction building */
44
+ export interface GeneratedKeypair {
45
+ /** Purpose of this keypair */
46
+ purpose: "stakeAccount" | "unstakeAccount" | "transferAuthority";
47
+ /** Public address (base58) */
48
+ address: string;
49
+ /** Secret key (base58) */
50
+ secretKey: string;
51
+ }
52
+ /** Result from building a transaction from intent */
53
+ export interface BuildFromIntentResult {
54
+ /** The built transaction */
55
+ transaction: Transaction;
56
+ /** Generated keypairs (for stake accounts, etc.) */
57
+ generatedKeypairs: GeneratedKeypair[];
58
+ }
59
+ /** Base intent - all intents have intentType */
60
+ export interface BaseIntent {
61
+ intentType: string;
62
+ memo?: string;
63
+ }
64
+ /** Payment intent */
65
+ export interface PaymentIntent extends BaseIntent {
66
+ intentType: "payment";
67
+ recipients?: Array<{
68
+ address?: {
69
+ address: string;
70
+ };
71
+ amount?: {
72
+ value: bigint;
73
+ symbol?: string;
74
+ };
75
+ }>;
76
+ }
77
+ /** Stake intent */
78
+ export interface StakeIntent extends BaseIntent {
79
+ intentType: "stake";
80
+ validatorAddress: string;
81
+ amount?: {
82
+ value: bigint;
83
+ };
84
+ stakingType?: "NATIVE" | "JITO" | "MARINADE";
85
+ stakePoolConfig?: StakePoolConfig;
86
+ }
87
+ /** Stake pool configuration (for Jito) */
88
+ export interface StakePoolConfig {
89
+ stakePoolAddress: string;
90
+ withdrawAuthority: string;
91
+ reserveStake: string;
92
+ destinationPoolAccount: string;
93
+ managerFeeAccount: string;
94
+ referralPoolAccount?: string;
95
+ poolMint: string;
96
+ validatorList?: string;
97
+ sourcePoolAccount?: string;
98
+ }
99
+ /** Unstake intent */
100
+ export interface UnstakeIntent extends BaseIntent {
101
+ intentType: "unstake";
102
+ stakingAddress: string;
103
+ validatorAddress?: string;
104
+ amount?: {
105
+ value: bigint;
106
+ };
107
+ remainingStakingAmount?: {
108
+ value: bigint;
109
+ };
110
+ stakingType?: "NATIVE" | "JITO" | "MARINADE";
111
+ stakePoolConfig?: StakePoolConfig;
112
+ }
113
+ /** Claim intent (withdraw from deactivated stake) */
114
+ export interface ClaimIntent extends BaseIntent {
115
+ intentType: "claim";
116
+ stakingAddress: string;
117
+ amount?: {
118
+ value: bigint;
119
+ };
120
+ }
121
+ /** Deactivate intent */
122
+ export interface DeactivateIntent extends BaseIntent {
123
+ intentType: "deactivate";
124
+ stakingAddress?: string;
125
+ stakingAddresses?: string[];
126
+ }
127
+ /** Delegate intent */
128
+ export interface DelegateIntent extends BaseIntent {
129
+ intentType: "delegate";
130
+ validatorAddress: string;
131
+ stakingAddress?: string;
132
+ stakingAddresses?: string[];
133
+ }
134
+ /** Enable token intent (create ATA) */
135
+ export interface EnableTokenIntent extends BaseIntent {
136
+ intentType: "enableToken";
137
+ recipientAddress?: string;
138
+ tokenAddress?: string;
139
+ tokenProgramId?: string;
140
+ }
141
+ /** Close ATA intent */
142
+ export interface CloseAtaIntent extends BaseIntent {
143
+ intentType: "closeAssociatedTokenAccount";
144
+ tokenAccountAddress?: string;
145
+ tokenProgramId?: string;
146
+ }
147
+ /** Consolidate intent - transfer from child address to root */
148
+ export interface ConsolidateIntent extends BaseIntent {
149
+ intentType: "consolidate";
150
+ /** The child address to consolidate from (sender) */
151
+ receiveAddress: string;
152
+ /** Recipients (root address for SOL, ATAs for tokens) */
153
+ recipients?: Array<{
154
+ address?: {
155
+ address: string;
156
+ };
157
+ amount?: {
158
+ value: bigint;
159
+ };
160
+ }>;
161
+ }
162
+ /** Union of all supported intent types */
163
+ export type SolanaIntent = PaymentIntent | StakeIntent | UnstakeIntent | ClaimIntent | DeactivateIntent | DelegateIntent | EnableTokenIntent | CloseAtaIntent | ConsolidateIntent;
164
+ /**
165
+ * Build a Solana transaction from a BitGo intent.
166
+ *
167
+ * This function passes the intent directly to Rust/WASM which handles
168
+ * all the intent-to-transaction mapping internally.
169
+ *
170
+ * @param intent - The BitGo intent (with intentType, etc.)
171
+ * @param params - Build parameters (feePayer, nonce)
172
+ * @returns Transaction object and any generated keypairs
173
+ *
174
+ * @example
175
+ * ```typescript
176
+ * // Payment intent
177
+ * const result = buildFromIntent(
178
+ * {
179
+ * intentType: 'payment',
180
+ * recipients: [{ address: { address: recipient }, amount: { value: 1000000n } }]
181
+ * },
182
+ * { feePayer: walletRoot, nonce: { type: 'blockhash', value: blockhash } }
183
+ * );
184
+ *
185
+ * // Native staking - generates a new stake account keypair
186
+ * const result = buildFromIntent(
187
+ * {
188
+ * intentType: 'stake',
189
+ * validatorAddress: validator,
190
+ * amount: { value: 1000000000n }
191
+ * },
192
+ * { feePayer: walletRoot, nonce: { type: 'blockhash', value: blockhash } }
193
+ * );
194
+ * // result.generatedKeypairs[0] contains the stake account keypair
195
+ * ```
196
+ */
197
+ export declare function buildFromIntent(intent: BaseIntent, params: BuildFromIntentParams): BuildFromIntentResult;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * High-level intent-based transaction building.
3
+ *
4
+ * This module provides `buildFromIntent()` which accepts BitGo intent objects
5
+ * directly and builds Solana transactions without requiring the caller to
6
+ * construct low-level instructions.
7
+ *
8
+ * The intent → transaction mapping happens entirely in Rust/WASM for simplicity.
9
+ *
10
+ * Usage:
11
+ * ```typescript
12
+ * import { buildFromIntent } from '@bitgo/wasm-solana';
13
+ *
14
+ * const result = buildFromIntent(intent, {
15
+ * feePayer: walletRootAddress,
16
+ * nonce: { type: 'blockhash', value: recentBlockhash },
17
+ * });
18
+ *
19
+ * // result.transaction - Transaction object
20
+ * // result.generatedKeypairs - any keypairs generated (e.g., stake accounts)
21
+ * ```
22
+ */
23
+ import { IntentNamespace } from "./wasm/wasm_solana.js";
24
+ import { Transaction } from "./transaction.js";
25
+ // =============================================================================
26
+ // Main Function
27
+ // =============================================================================
28
+ /**
29
+ * Build a Solana transaction from a BitGo intent.
30
+ *
31
+ * This function passes the intent directly to Rust/WASM which handles
32
+ * all the intent-to-transaction mapping internally.
33
+ *
34
+ * @param intent - The BitGo intent (with intentType, etc.)
35
+ * @param params - Build parameters (feePayer, nonce)
36
+ * @returns Transaction object and any generated keypairs
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * // Payment intent
41
+ * const result = buildFromIntent(
42
+ * {
43
+ * intentType: 'payment',
44
+ * recipients: [{ address: { address: recipient }, amount: { value: 1000000n } }]
45
+ * },
46
+ * { feePayer: walletRoot, nonce: { type: 'blockhash', value: blockhash } }
47
+ * );
48
+ *
49
+ * // Native staking - generates a new stake account keypair
50
+ * const result = buildFromIntent(
51
+ * {
52
+ * intentType: 'stake',
53
+ * validatorAddress: validator,
54
+ * amount: { value: 1000000000n }
55
+ * },
56
+ * { feePayer: walletRoot, nonce: { type: 'blockhash', value: blockhash } }
57
+ * );
58
+ * // result.generatedKeypairs[0] contains the stake account keypair
59
+ * ```
60
+ */
61
+ export function buildFromIntent(intent, params) {
62
+ const result = IntentNamespace.build_from_intent(intent, params);
63
+ return {
64
+ transaction: Transaction.fromWasm(result.transaction),
65
+ generatedKeypairs: result.generatedKeypairs,
66
+ };
67
+ }
@@ -8,6 +8,11 @@ import { WasmKeypair } from "./wasm/wasm_solana.js";
8
8
  export declare class Keypair {
9
9
  private _wasm;
10
10
  private constructor();
11
+ /**
12
+ * Generate a new random keypair
13
+ * @returns A new Keypair instance with randomly generated keys
14
+ */
15
+ static generate(): Keypair;
11
16
  /**
12
17
  * Create a keypair from a 32-byte secret key
13
18
  * @param secretKey - The 32-byte Ed25519 secret key
@@ -10,6 +10,14 @@ export class Keypair {
10
10
  constructor(_wasm) {
11
11
  this._wasm = _wasm;
12
12
  }
13
+ /**
14
+ * Generate a new random keypair
15
+ * @returns A new Keypair instance with randomly generated keys
16
+ */
17
+ static generate() {
18
+ const wasm = WasmKeypair.generate();
19
+ return new Keypair(wasm);
20
+ }
13
21
  /**
14
22
  * Create a keypair from a 32-byte secret key
15
23
  * @param secretKey - The 32-byte Ed25519 secret key
@@ -72,7 +72,7 @@ export declare class Transaction {
72
72
  * Get the transaction ID (first signature as base58).
73
73
  *
74
74
  * For Solana, the transaction ID is the first signature.
75
- * Returns "UNSIGNED" if the transaction has no valid signatures.
75
+ * Returns `undefined` if the transaction is unsigned (no signatures or all-zeros signature).
76
76
  *
77
77
  * @example
78
78
  * ```typescript
@@ -81,7 +81,7 @@ export declare class Transaction {
81
81
  * console.log(tx.id); // Base58 encoded signature
82
82
  * ```
83
83
  */
84
- get id(): string;
84
+ get id(): string | undefined;
85
85
  /**
86
86
  * Get the signable message payload (what gets signed)
87
87
  * This is the serialized message that signers sign
@@ -91,10 +91,9 @@ export declare class Transaction {
91
91
  /**
92
92
  * Serialize the message portion of the transaction.
93
93
  * Alias for signablePayload() - provides compatibility with @solana/web3.js API.
94
- * Returns a Buffer for compatibility with code expecting .toString('base64').
95
- * @returns The serialized message bytes as a Buffer
94
+ * @returns The serialized message bytes
96
95
  */
97
- serializeMessage(): Buffer;
96
+ serializeMessage(): Uint8Array;
98
97
  /**
99
98
  * Serialize the transaction to bytes
100
99
  * @returns The serialized transaction bytes
@@ -63,7 +63,7 @@ export class Transaction {
63
63
  * Get the transaction ID (first signature as base58).
64
64
  *
65
65
  * For Solana, the transaction ID is the first signature.
66
- * Returns "UNSIGNED" if the transaction has no valid signatures.
66
+ * Returns `undefined` if the transaction is unsigned (no signatures or all-zeros signature).
67
67
  *
68
68
  * @example
69
69
  * ```typescript
@@ -86,11 +86,10 @@ export class Transaction {
86
86
  /**
87
87
  * Serialize the message portion of the transaction.
88
88
  * Alias for signablePayload() - provides compatibility with @solana/web3.js API.
89
- * Returns a Buffer for compatibility with code expecting .toString('base64').
90
- * @returns The serialized message bytes as a Buffer
89
+ * @returns The serialized message bytes
91
90
  */
92
91
  serializeMessage() {
93
- return Buffer.from(this.signablePayload());
92
+ return this.signablePayload();
94
93
  }
95
94
  /**
96
95
  * Serialize the transaction to bytes
@@ -63,10 +63,6 @@ export declare class VersionedTransaction {
63
63
  * Automatically handles both legacy and versioned formats.
64
64
  */
65
65
  static fromBytes(bytes: Uint8Array): VersionedTransaction;
66
- /**
67
- * Deserialize a transaction from base64 string.
68
- */
69
- static fromBase64(base64: string): VersionedTransaction;
70
66
  /**
71
67
  * Create a VersionedTransaction from a WasmVersionedTransaction instance.
72
68
  * @internal Used by builder functions
@@ -126,9 +122,9 @@ export declare class VersionedTransaction {
126
122
  * Get the transaction ID (first signature as base58).
127
123
  *
128
124
  * For Solana, the transaction ID is the first signature.
129
- * Returns "UNSIGNED" if the transaction has no valid signatures.
125
+ * Returns `undefined` if the transaction is unsigned (no signatures or all-zeros signature).
130
126
  */
131
- get id(): string;
127
+ get id(): string | undefined;
132
128
  /**
133
129
  * Get the signable message payload.
134
130
  */
@@ -136,18 +132,13 @@ export declare class VersionedTransaction {
136
132
  /**
137
133
  * Serialize the message portion of the transaction.
138
134
  * Alias for signablePayload() - provides compatibility with @solana/web3.js API.
139
- * Returns a Buffer for compatibility with code expecting .toString('base64').
140
- * @returns The serialized message bytes as a Buffer
135
+ * @returns The serialized message bytes
141
136
  */
142
- serializeMessage(): Buffer;
137
+ serializeMessage(): Uint8Array;
143
138
  /**
144
139
  * Serialize the transaction to bytes.
145
140
  */
146
141
  toBytes(): Uint8Array;
147
- /**
148
- * Serialize the transaction to base64.
149
- */
150
- toBase64(): string;
151
142
  /**
152
143
  * Serialize to network broadcast format.
153
144
  * @returns The transaction as bytes ready for broadcast
@@ -33,13 +33,6 @@ export class VersionedTransaction {
33
33
  static fromBytes(bytes) {
34
34
  return new VersionedTransaction(WasmVersionedTransaction.from_bytes(bytes));
35
35
  }
36
- /**
37
- * Deserialize a transaction from base64 string.
38
- */
39
- static fromBase64(base64) {
40
- const bytes = Uint8Array.from(Buffer.from(base64, "base64"));
41
- return VersionedTransaction.fromBytes(bytes);
42
- }
43
36
  /**
44
37
  * Create a VersionedTransaction from a WasmVersionedTransaction instance.
45
38
  * @internal Used by builder functions
@@ -115,7 +108,7 @@ export class VersionedTransaction {
115
108
  * Get the transaction ID (first signature as base58).
116
109
  *
117
110
  * For Solana, the transaction ID is the first signature.
118
- * Returns "UNSIGNED" if the transaction has no valid signatures.
111
+ * Returns `undefined` if the transaction is unsigned (no signatures or all-zeros signature).
119
112
  */
120
113
  get id() {
121
114
  return this.inner.id;
@@ -129,11 +122,10 @@ export class VersionedTransaction {
129
122
  /**
130
123
  * Serialize the message portion of the transaction.
131
124
  * Alias for signablePayload() - provides compatibility with @solana/web3.js API.
132
- * Returns a Buffer for compatibility with code expecting .toString('base64').
133
- * @returns The serialized message bytes as a Buffer
125
+ * @returns The serialized message bytes
134
126
  */
135
127
  serializeMessage() {
136
- return Buffer.from(this.signablePayload());
128
+ return this.signablePayload();
137
129
  }
138
130
  /**
139
131
  * Serialize the transaction to bytes.
@@ -141,12 +133,6 @@ export class VersionedTransaction {
141
133
  toBytes() {
142
134
  return this.inner.to_bytes();
143
135
  }
144
- /**
145
- * Serialize the transaction to base64.
146
- */
147
- toBase64() {
148
- return Buffer.from(this.toBytes()).toString("base64");
149
- }
150
136
  /**
151
137
  * Serialize to network broadcast format.
152
138
  * @returns The transaction as bytes ready for broadcast
@@ -372,6 +372,48 @@ export class Instructions {
372
372
  push(instruction: Instruction): void;
373
373
  }
374
374
 
375
+ export class IntentNamespace {
376
+ private constructor();
377
+ free(): void;
378
+ [Symbol.dispose](): void;
379
+ /**
380
+ * Build a transaction directly from a BitGo intent.
381
+ *
382
+ * This function takes the full intent as-is and builds the transaction
383
+ * without requiring the caller to construct instructions.
384
+ *
385
+ * # Arguments
386
+ *
387
+ * * `intent` - The full BitGo intent object (with intentType, etc.)
388
+ * * `params` - Build parameters: { feePayer, nonce }
389
+ *
390
+ * # Returns
391
+ *
392
+ * An object with:
393
+ * * `transaction` - WasmTransaction object
394
+ * * `generatedKeypairs` - Array of keypairs generated (for stake accounts, etc.)
395
+ *
396
+ * # Example
397
+ *
398
+ * ```javascript
399
+ * const result = IntentNamespace.build_from_intent(
400
+ * {
401
+ * intentType: 'stake',
402
+ * validatorAddress: '...',
403
+ * amount: { value: 1000000000n }
404
+ * },
405
+ * {
406
+ * feePayer: 'DgT9...',
407
+ * nonce: { type: 'blockhash', value: 'GWaQ...' }
408
+ * }
409
+ * );
410
+ * // result.transaction - WasmTransaction object
411
+ * // result.generatedKeypairs - [{ purpose, address, secretKey }]
412
+ * ```
413
+ */
414
+ static build_from_intent(intent: any, params: any): any;
415
+ }
416
+
375
417
  export class Keypair {
376
418
  free(): void;
377
419
  [Symbol.dispose](): void;
@@ -697,6 +739,10 @@ export class WasmKeypair {
697
739
  * Get the address as a base58 string.
698
740
  */
699
741
  address(): string;
742
+ /**
743
+ * Generate a new random keypair.
744
+ */
745
+ static generate(): WasmKeypair;
700
746
  /**
701
747
  * Get the public key as a base58 string.
702
748
  */
@@ -808,9 +854,9 @@ export class WasmTransaction {
808
854
  * Get the transaction ID (first signature as base58).
809
855
  *
810
856
  * For Solana, the transaction ID is the first signature.
811
- * Returns "UNSIGNED" if the first signature is all zeros (unsigned transaction).
857
+ * Returns `undefined` if the transaction is unsigned (no signatures or all-zeros signature).
812
858
  */
813
- readonly id: string;
859
+ readonly id: string | undefined;
814
860
  /**
815
861
  * Get the fee payer address as a base58 string.
816
862
  *
@@ -902,9 +948,9 @@ export class WasmVersionedTransaction {
902
948
  * Get the transaction ID (first signature as base58).
903
949
  *
904
950
  * For Solana, the transaction ID is the first signature.
905
- * Returns "UNSIGNED" if the first signature is all zeros (unsigned transaction).
951
+ * Returns `undefined` if the transaction is unsigned (no signatures or all-zeros signature).
906
952
  */
907
- readonly id: string;
953
+ readonly id: string | undefined;
908
954
  /**
909
955
  * Get the fee payer address as a base58 string.
910
956
  */