-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
150 lines (123 loc) · 4.39 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
const Stellar = require('stellar-sdk');
const fetch = require('node-fetch');
const horizonTestnet = new Stellar.Server(
'https://horizon-testnet.stellar.org',
);
function logError(error) {
console.error('An error occured: ', error);
}
function logInfo(...info) {
console.log(...info);
}
function generateKeys() {
return Stellar.Keypair.random();
}
async function fundAccount(publicKey) {
try {
const response = await fetch(
`https://friendbot.stellar.org?addr=${publicKey}`,
);
return response.json();
} catch (error) {
logError(error);
}
}
async function accountDetail(publicKey) {
try {
const account = await horizonTestnet.loadAccount(publicKey);
return account;
} catch (error) {
logError(error);
}
}
function displayAccount({ sequence, balances, signers }, showSigners = false) {
let response = {
sequence,
balance: balances[0].balance,
}
if (showSigners) {
response['signers'] = signers;
}
return response;
}
async function createPreauthTx() {
try {
logInfo('Start script...');
const senderKp = generateKeys();
logInfo('Generated sender account: ', senderKp.publicKey());
logInfo('Funding account...');
await fundAccount(senderKp.publicKey());
const senderAccount = await accountDetail(senderKp.publicKey());
logInfo('Sender: ', displayAccount(senderAccount));
const receiverKp = generateKeys();
logInfo('Generated receiver account: ', receiverKp.publicKey());
logInfo('Funding account...');
await fundAccount(receiverKp.publicKey());
let receiverAccount = await accountDetail(receiverKp.publicKey());
logInfo('Receiver: ', displayAccount(receiverAccount));
logInfo('Building future payment operation. Send 5000XLM to receiver...');
const paymentOp = Stellar.Operation.payment({
destination: receiverKp.publicKey(),
asset: Stellar.Asset.native(),
amount: '5000',
source: senderKp.publicKey(),
});
// The goal is to increment the sequence number by 2, but we only call
// incrementSequenceNumber() once here because the transaction builder also
// auto increments the sequence number.
senderAccount.incrementSequenceNumber();
logInfo(
'Sender sequence number incremented to: ',
senderAccount.sequenceNumber(),
);
// build the future tx with incremented sequence number
const futureTx = new Stellar.TransactionBuilder(senderAccount, {
fee: Stellar.BASE_FEE,
networkPassphrase: Stellar.Networks.TESTNET,
})
.addOperation(paymentOp)
.setTimeout(Stellar.TimeoutInfinite)
.build();
logInfo('futureTx XDR: ', futureTx.toXDR());
logInfo('Add the hash of the future tx as a signer on sender ...');
const setOptions = Stellar.Operation.setOptions({
signer: {
preAuthTx: futureTx.hash(),
weight: 1,
},
});
// get the sender account with the current sequence number.
let currentSenderDetail = await accountDetail(senderKp.publicKey());
const addSignerTx = new Stellar.TransactionBuilder(currentSenderDetail, {
fee: Stellar.BASE_FEE,
networkPassphrase: Stellar.Networks.TESTNET,
})
.setTimeout(Stellar.TimeoutInfinite)
.addOperation(setOptions)
.build();
addSignerTx.sign(Stellar.Keypair.fromSecret(senderKp.secret()));
await horizonTestnet.submitTransaction(addSignerTx);
logInfo('signer successfully added.');
logInfo('Check sender for extra signer...')
currentSenderDetail = await accountDetail(senderKp.publicKey());
logInfo('Sender: ', displayAccount(currentSenderDetail, true));
logInfo('Submit pre-authorized tx...');
// Notice how we don't need to sign the transaction because it is pre-authorized.
await horizonTestnet.submitTransaction(futureTx);
logInfo('pre-authorized tx successful');
logInfo('Checking sender account....')
currentSenderDetail = await accountDetail(senderKp.publicKey());
logInfo('Sender: ', displayAccount(currentSenderDetail, true));
logInfo('Checking receiver account....')
receiverAccount = await accountDetail(receiverKp.publicKey());
logInfo('Receiver: ', displayAccount(receiverAccount));
logInfo('End script. Visit https://oliha.dev for questions and comments.');
} catch (error) {
if (error.response && error.response.data) {
logError(error.response.data);
} else {
logError(error);
}
}
}
createPreauthTx();