2018-09-19 17:35:16 -07:00
|
|
|
/*
|
2018-09-26 09:49:59 -07:00
|
|
|
Example of using the Budget program to perform a payment authorized by two parties
|
2018-09-19 17:35:16 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
//eslint-disable-next-line import/no-commonjs
|
|
|
|
const solanaWeb3 = require('..');
|
|
|
|
//const solanaWeb3 = require('@solana/web3.js');
|
|
|
|
|
|
|
|
const account1 = new solanaWeb3.Account();
|
|
|
|
const account2 = new solanaWeb3.Account();
|
|
|
|
const contractState = new solanaWeb3.Account();
|
|
|
|
|
2018-09-26 09:49:59 -07:00
|
|
|
const approver1 = new solanaWeb3.Account();
|
|
|
|
const approver2 = new solanaWeb3.Account();
|
|
|
|
|
2018-09-19 17:35:16 -07:00
|
|
|
let url;
|
|
|
|
url = 'http://localhost:8899';
|
|
|
|
//url = 'http://testnet.solana.com:8899';
|
|
|
|
const connection = new solanaWeb3.Connection(url);
|
|
|
|
|
2019-07-18 15:35:01 -06:00
|
|
|
function getTransactionFee() {
|
|
|
|
return connection.getRecentBlockhash().then(response => {
|
|
|
|
return response[1];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-09-19 17:35:16 -07:00
|
|
|
function showBalance() {
|
|
|
|
console.log(`\n== Account State`);
|
|
|
|
return Promise.all([
|
|
|
|
connection.getBalance(account1.publicKey),
|
|
|
|
connection.getBalance(account2.publicKey),
|
|
|
|
connection.getBalance(contractState.publicKey),
|
2019-05-24 16:07:16 -06:00
|
|
|
]).then(([fromBalance, toBalance, contractStateBalance]) => {
|
|
|
|
console.log(
|
|
|
|
`Account1: ${account1.publicKey} has a balance of ${fromBalance}`,
|
|
|
|
);
|
|
|
|
console.log(
|
|
|
|
`Account2: ${account2.publicKey} has a balance of ${toBalance}`,
|
|
|
|
);
|
|
|
|
console.log(
|
2019-06-26 09:31:04 -07:00
|
|
|
`Contract State: ${contractState.publicKey} has a balance of ${contractStateBalance}`,
|
2019-05-24 16:07:16 -06:00
|
|
|
);
|
|
|
|
});
|
2018-09-19 17:35:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
function confirmTransaction(signature) {
|
|
|
|
console.log('Confirming transaction:', signature);
|
2018-11-04 11:41:21 -08:00
|
|
|
return connection.getSignatureStatus(signature).then(confirmation => {
|
2019-05-24 16:07:16 -06:00
|
|
|
if (confirmation && 'Ok' in confirmation) {
|
|
|
|
console.log('Transaction confirmed');
|
|
|
|
} else if (confirmation) {
|
|
|
|
throw new Error(
|
|
|
|
`Transaction was not confirmed (${JSON.stringify(confirmation.Err)})`,
|
|
|
|
);
|
|
|
|
} else {
|
2018-09-26 19:16:17 -07:00
|
|
|
throw new Error(`Transaction was not confirmed (${confirmation})`);
|
2018-09-19 17:35:16 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-07-18 15:35:01 -06:00
|
|
|
function airDrop(feeCalculator) {
|
|
|
|
const airdrop = 100 + 3 * feeCalculator.targetLamportsPerSignature;
|
|
|
|
console.log(`\n== Requesting airdrop of ${airdrop} to ${account1.publicKey}`);
|
2018-11-04 11:41:21 -08:00
|
|
|
return connection
|
2019-07-18 15:35:01 -06:00
|
|
|
.requestAirdrop(account1.publicKey, airdrop)
|
2018-11-04 11:41:21 -08:00
|
|
|
.then(confirmTransaction);
|
2018-09-19 17:35:16 -07:00
|
|
|
}
|
|
|
|
|
2019-07-18 15:35:01 -06:00
|
|
|
getTransactionFee().then(feeCalculator => {
|
|
|
|
showBalance()
|
|
|
|
.then(airDrop(feeCalculator))
|
|
|
|
.then(() => {
|
|
|
|
console.log(`\n== Move 1 lamport to approver1`);
|
|
|
|
const transaction = solanaWeb3.SystemProgram.transfer(
|
|
|
|
account1.publicKey,
|
|
|
|
approver1.publicKey,
|
|
|
|
1 + feeCalculator.lamportsPerSignature,
|
|
|
|
);
|
|
|
|
return solanaWeb3.sendAndConfirmTransaction(
|
|
|
|
connection,
|
|
|
|
transaction,
|
|
|
|
account1,
|
|
|
|
);
|
|
|
|
})
|
|
|
|
.then(confirmTransaction)
|
|
|
|
.then(getTransactionFee)
|
|
|
|
.then(() => {
|
|
|
|
console.log(`\n== Move 1 lamport to approver2`);
|
|
|
|
const transaction = solanaWeb3.SystemProgram.transfer(
|
|
|
|
account1.publicKey,
|
|
|
|
approver2.publicKey,
|
|
|
|
1 + feeCalculator.lamportsPerSignature,
|
|
|
|
);
|
|
|
|
return solanaWeb3.sendAndConfirmTransaction(
|
|
|
|
connection,
|
|
|
|
transaction,
|
|
|
|
account1,
|
|
|
|
);
|
|
|
|
})
|
|
|
|
.then(confirmTransaction)
|
|
|
|
.then(showBalance)
|
|
|
|
.then(() => {
|
|
|
|
console.log(`\n== Initializing contract`);
|
|
|
|
const transaction = solanaWeb3.BudgetProgram.payOnBoth(
|
|
|
|
account1.publicKey,
|
|
|
|
contractState.publicKey,
|
|
|
|
account2.publicKey,
|
|
|
|
50,
|
|
|
|
solanaWeb3.BudgetProgram.signatureCondition(approver1.publicKey),
|
|
|
|
solanaWeb3.BudgetProgram.signatureCondition(approver2.publicKey),
|
|
|
|
);
|
|
|
|
return solanaWeb3.sendAndConfirmTransaction(
|
|
|
|
connection,
|
|
|
|
transaction,
|
|
|
|
account1,
|
|
|
|
);
|
|
|
|
})
|
|
|
|
.then(confirmTransaction)
|
|
|
|
.then(showBalance)
|
|
|
|
.then(() => {
|
|
|
|
console.log(`\n== Apply approver 1`);
|
|
|
|
const transaction = solanaWeb3.BudgetProgram.applySignature(
|
|
|
|
approver1.publicKey,
|
|
|
|
contractState.publicKey,
|
|
|
|
account2.publicKey,
|
|
|
|
);
|
|
|
|
return solanaWeb3.sendAndConfirmTransaction(
|
|
|
|
connection,
|
|
|
|
transaction,
|
|
|
|
approver1,
|
|
|
|
);
|
|
|
|
})
|
|
|
|
.then(confirmTransaction)
|
|
|
|
.then(showBalance)
|
|
|
|
.then(() => {
|
|
|
|
console.log(`\n== Apply approver 2`);
|
|
|
|
const transaction = solanaWeb3.BudgetProgram.applySignature(
|
|
|
|
approver2.publicKey,
|
|
|
|
contractState.publicKey,
|
|
|
|
account2.publicKey,
|
|
|
|
);
|
|
|
|
return solanaWeb3.sendAndConfirmTransaction(
|
|
|
|
connection,
|
|
|
|
transaction,
|
|
|
|
approver2,
|
|
|
|
);
|
|
|
|
})
|
|
|
|
.then(confirmTransaction)
|
|
|
|
.then(showBalance)
|
2018-09-19 17:35:16 -07:00
|
|
|
|
2019-07-18 15:35:01 -06:00
|
|
|
.then(() => {
|
|
|
|
console.log('\nDone');
|
|
|
|
})
|
2018-09-19 17:35:16 -07:00
|
|
|
|
2019-07-18 15:35:01 -06:00
|
|
|
.catch(err => {
|
|
|
|
console.log(err);
|
|
|
|
});
|
|
|
|
});
|