|
| 1 | +import * as StellarSDK from '@stellar/stellar-sdk'; |
| 2 | +import { |
| 3 | + PreparedTransaction, |
| 4 | + UnsignedTransaction, |
| 5 | + SignedTransaction, |
| 6 | + SubmissionResult |
| 7 | +} from './offline-preparation'; |
| 8 | + |
| 9 | +/** Deterministic mock source public key (G...) */ |
| 10 | +export const FIXTURE_SOURCE_PK = 'GBEDH75BXETOM2UPESSCHDVGV7XRDKS74YUKXTC7LR627DQ3SUZIJG3Y'; |
| 11 | +/** Deterministic mock destination public key (G...) */ |
| 12 | +export const FIXTURE_DESTINATION_PK = 'GBAW5KWLZU5PEUMR4PWXJVGFXDT4FRYIOKKTU74O5CGB24RWJS36LICH'; |
| 13 | +/** Deterministic mock secret key (S...) matching the source public key */ |
| 14 | +export const FIXTURE_SOURCE_SK = 'SDUTB2DT5NIGRKSGUHEU3TSZ4UJ45CJ3KVDSAKOOMHZEI64F2M4EIJCD'; |
| 15 | +/** We use Stellar Testnet as the deterministic network */ |
| 16 | +export const FIXTURE_NETWORK = StellarSDK.Networks.TESTNET; |
| 17 | + |
| 18 | +/** |
| 19 | + * Creates a deterministic PreparedTransaction fixture. |
| 20 | + * |
| 21 | + * @param overrides Optional overrides for the prepared transaction properties |
| 22 | + * @returns A deterministic PreparedTransaction |
| 23 | + */ |
| 24 | +export function createPreparedTransactionFixture(overrides?: Partial<PreparedTransaction>): PreparedTransaction { |
| 25 | + return { |
| 26 | + sourcePublicKey: FIXTURE_SOURCE_PK, |
| 27 | + networkPassphrase: FIXTURE_NETWORK, |
| 28 | + operations: [{ |
| 29 | + destination: FIXTURE_DESTINATION_PK, |
| 30 | + amount: '10', |
| 31 | + asset: { code: 'XLM' } |
| 32 | + }], |
| 33 | + timebounds: { minTime: 1700000000, maxTime: 1700000300 }, |
| 34 | + baseFee: '100', |
| 35 | + networkState: { sequence: '1234567890', fetchedAt: 1700000000 }, |
| 36 | + readyToBuild: true, |
| 37 | + ...overrides |
| 38 | + }; |
| 39 | +} |
| 40 | + |
| 41 | +/** |
| 42 | + * Creates a deterministic UnsignedTransaction fixture containing a real StellarSDK.Transaction. |
| 43 | + * |
| 44 | + * @param overrides Optional overrides for the PreparedTransaction used to build it |
| 45 | + * @returns A deterministic UnsignedTransaction |
| 46 | + */ |
| 47 | +export function createUnsignedTransactionFixture(overrides?: Partial<PreparedTransaction>): UnsignedTransaction { |
| 48 | + const prepared = createPreparedTransactionFixture(overrides); |
| 49 | + |
| 50 | + const account = new StellarSDK.Account( |
| 51 | + prepared.sourcePublicKey, |
| 52 | + prepared.networkState.sequence |
| 53 | + ); |
| 54 | + |
| 55 | + const builder = new StellarSDK.TransactionBuilder(account, { |
| 56 | + fee: prepared.baseFee, |
| 57 | + networkPassphrase: prepared.networkPassphrase, |
| 58 | + timebounds: prepared.timebounds, |
| 59 | + }); |
| 60 | + |
| 61 | + for (const op of prepared.operations) { |
| 62 | + builder.addOperation( |
| 63 | + StellarSDK.Operation.payment({ |
| 64 | + destination: op.destination, |
| 65 | + asset: StellarSDK.Asset.native(), // For simplicity in fixture, we assume native if XLM |
| 66 | + amount: op.amount, |
| 67 | + }) |
| 68 | + ); |
| 69 | + } |
| 70 | + |
| 71 | + if (prepared.memo) { |
| 72 | + builder.addMemo(StellarSDK.Memo.text(prepared.memo)); |
| 73 | + } |
| 74 | + |
| 75 | + const transaction = builder.build(); |
| 76 | + |
| 77 | + return { |
| 78 | + transaction, |
| 79 | + networkPassphrase: prepared.networkPassphrase, |
| 80 | + sourcePublicKey: prepared.sourcePublicKey, |
| 81 | + hash: transaction.hash().toString('hex'), |
| 82 | + }; |
| 83 | +} |
| 84 | + |
| 85 | +/** |
| 86 | + * Creates a deterministic SignedTransaction fixture. |
| 87 | + * Note: Since we need a real signature, this uses a dummy keypair to sign the mock transaction. |
| 88 | + * |
| 89 | + * @param secretKey Optional valid secret key to sign with. If omitted, a deterministic dummy key is used. |
| 90 | + * @param overrides Optional overrides for the underlying transaction |
| 91 | + * @returns A deterministic SignedTransaction |
| 92 | + */ |
| 93 | +export function createSignedTransactionFixture( |
| 94 | + secretKey: string = FIXTURE_SOURCE_SK, |
| 95 | + overrides?: Partial<PreparedTransaction> |
| 96 | +): SignedTransaction { |
| 97 | + const unsigned = createUnsignedTransactionFixture(overrides); |
| 98 | + const keypair = StellarSDK.Keypair.fromSecret(secretKey); |
| 99 | + |
| 100 | + unsigned.transaction.sign(keypair); |
| 101 | + |
| 102 | + return { |
| 103 | + transaction: unsigned.transaction, |
| 104 | + networkPassphrase: unsigned.networkPassphrase, |
| 105 | + hash: unsigned.transaction.hash().toString('hex'), |
| 106 | + xdr: unsigned.transaction.toEnvelope().toXDR('base64'), |
| 107 | + }; |
| 108 | +} |
| 109 | + |
| 110 | +/** |
| 111 | + * Creates a deterministic SubmissionResult fixture. |
| 112 | + * |
| 113 | + * @param status The status of the submission ('success', 'failed', 'unknown') |
| 114 | + * @param overrides Optional overrides for the SubmissionResult properties |
| 115 | + * @returns A deterministic SubmissionResult |
| 116 | + */ |
| 117 | +export function createSubmissionResultFixture( |
| 118 | + status: 'success' | 'failed' | 'unknown', |
| 119 | + overrides?: Partial<SubmissionResult> |
| 120 | +): SubmissionResult { |
| 121 | + if (status === 'success') { |
| 122 | + return { |
| 123 | + success: true, |
| 124 | + hash: 'a1b2c3d4e5f678901234567890abcdef1234567890abcdef1234567890abcdef', |
| 125 | + ledger: 12345, |
| 126 | + fee: '100', |
| 127 | + ...overrides |
| 128 | + }; |
| 129 | + } else if (status === 'failed') { |
| 130 | + return { |
| 131 | + success: false, |
| 132 | + hash: 'f6e5d4c3b2a109876543210987fedcba0987654321fedcba0987654321fedcba', |
| 133 | + error: 'Transaction failed on network', |
| 134 | + errorCode: 'TX_FAILED', |
| 135 | + ...overrides |
| 136 | + }; |
| 137 | + } else { |
| 138 | + // unknown |
| 139 | + return { |
| 140 | + success: false, |
| 141 | + hash: '0000000000000000000000000000000000000000000000000000000000000000', |
| 142 | + error: 'Transaction status unknown due to timeout', |
| 143 | + errorCode: 'TX_STATUS_UNKNOWN', |
| 144 | + ...overrides |
| 145 | + }; |
| 146 | + } |
| 147 | +} |
0 commit comments