fix: Squash budget bugs
This commit is contained in:
parent
c99d8dd15c
commit
87c1becbef
|
@ -9,7 +9,6 @@ const solanaWeb3 = require('..');
|
||||||
|
|
||||||
const account1 = new solanaWeb3.Account();
|
const account1 = new solanaWeb3.Account();
|
||||||
const account2 = new solanaWeb3.Account();
|
const account2 = new solanaWeb3.Account();
|
||||||
const contractFunds = new solanaWeb3.Account();
|
|
||||||
const contractState = new solanaWeb3.Account();
|
const contractState = new solanaWeb3.Account();
|
||||||
|
|
||||||
let url;
|
let url;
|
||||||
|
@ -23,28 +22,20 @@ function showBalance() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
connection.getBalance(account1.publicKey),
|
connection.getBalance(account1.publicKey),
|
||||||
connection.getBalance(account2.publicKey),
|
connection.getBalance(account2.publicKey),
|
||||||
connection.getBalance(contractFunds.publicKey),
|
|
||||||
connection.getBalance(contractState.publicKey),
|
connection.getBalance(contractState.publicKey),
|
||||||
]).then(
|
]).then(([fromBalance, toBalance, contractStateBalance]) => {
|
||||||
([fromBalance, toBalance, contractFundsBalance, contractStateBalance]) => {
|
console.log(
|
||||||
console.log(
|
`Account1: ${account1.publicKey} has a balance of ${fromBalance}`,
|
||||||
`Account1: ${account1.publicKey} has a balance of ${fromBalance}`,
|
);
|
||||||
);
|
console.log(
|
||||||
console.log(
|
`Account2: ${account2.publicKey} has a balance of ${toBalance}`,
|
||||||
`Account2: ${account2.publicKey} has a balance of ${toBalance}`,
|
);
|
||||||
);
|
console.log(
|
||||||
console.log(
|
`Contract State: ${
|
||||||
`Contract Funds: ${
|
contractState.publicKey
|
||||||
contractFunds.publicKey
|
} has a balance of ${contractStateBalance}`,
|
||||||
} has a balance of ${contractFundsBalance}`,
|
);
|
||||||
);
|
});
|
||||||
console.log(
|
|
||||||
`Contract State: ${
|
|
||||||
contractState.publicKey
|
|
||||||
} has a balance of ${contractStateBalance}`,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirmTransaction(signature) {
|
function confirmTransaction(signature) {
|
||||||
|
@ -52,6 +43,10 @@ function confirmTransaction(signature) {
|
||||||
return connection.getSignatureStatus(signature).then(confirmation => {
|
return connection.getSignatureStatus(signature).then(confirmation => {
|
||||||
if (confirmation && 'Ok' in confirmation) {
|
if (confirmation && 'Ok' in confirmation) {
|
||||||
console.log('Transaction confirmed');
|
console.log('Transaction confirmed');
|
||||||
|
} else if (confirmation) {
|
||||||
|
throw new Error(
|
||||||
|
`Transaction was not confirmed (${JSON.stringify(confirmation.Err)})`,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Transaction was not confirmed (${confirmation})`);
|
throw new Error(`Transaction was not confirmed (${confirmation})`);
|
||||||
}
|
}
|
||||||
|
@ -68,36 +63,10 @@ function airDrop() {
|
||||||
showBalance()
|
showBalance()
|
||||||
.then(airDrop)
|
.then(airDrop)
|
||||||
.then(showBalance)
|
.then(showBalance)
|
||||||
.then(() => {
|
|
||||||
console.log(`\n== Creating account for the contract funds`);
|
|
||||||
const transaction = solanaWeb3.SystemProgram.createAccount(
|
|
||||||
account1.publicKey,
|
|
||||||
contractFunds.publicKey,
|
|
||||||
50, // number of lamports to transfer
|
|
||||||
0,
|
|
||||||
solanaWeb3.BudgetProgram.programId,
|
|
||||||
);
|
|
||||||
return connection.sendTransaction(transaction, account1);
|
|
||||||
})
|
|
||||||
.then(confirmTransaction)
|
|
||||||
.then(showBalance)
|
|
||||||
.then(() => {
|
|
||||||
console.log(`\n== Creating account for the contract state`);
|
|
||||||
const transaction = solanaWeb3.SystemProgram.createAccount(
|
|
||||||
account1.publicKey,
|
|
||||||
contractState.publicKey,
|
|
||||||
1, // account1 pays 1 lamport to hold the contract state
|
|
||||||
solanaWeb3.BudgetProgram.space,
|
|
||||||
solanaWeb3.BudgetProgram.programId,
|
|
||||||
);
|
|
||||||
return connection.sendTransaction(transaction, account1);
|
|
||||||
})
|
|
||||||
.then(confirmTransaction)
|
|
||||||
.then(showBalance)
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log(`\n== Initializing contract`);
|
console.log(`\n== Initializing contract`);
|
||||||
const transaction = solanaWeb3.BudgetProgram.pay(
|
const transaction = solanaWeb3.BudgetProgram.pay(
|
||||||
contractFunds.publicKey,
|
account1.publicKey,
|
||||||
contractState.publicKey,
|
contractState.publicKey,
|
||||||
account2.publicKey,
|
account2.publicKey,
|
||||||
50,
|
50,
|
||||||
|
@ -106,7 +75,11 @@ showBalance()
|
||||||
new Date('2050'),
|
new Date('2050'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return connection.sendTransaction(transaction, contractFunds);
|
return solanaWeb3.sendAndConfirmTransaction(
|
||||||
|
connection,
|
||||||
|
transaction,
|
||||||
|
account1,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.then(confirmTransaction)
|
.then(confirmTransaction)
|
||||||
.then(showBalance)
|
.then(showBalance)
|
||||||
|
@ -118,7 +91,11 @@ showBalance()
|
||||||
account2.publicKey,
|
account2.publicKey,
|
||||||
new Date('2050'),
|
new Date('2050'),
|
||||||
);
|
);
|
||||||
return connection.sendTransaction(transaction, account1);
|
return solanaWeb3.sendAndConfirmTransaction(
|
||||||
|
connection,
|
||||||
|
transaction,
|
||||||
|
account1,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.then(confirmTransaction)
|
.then(confirmTransaction)
|
||||||
.then(showBalance)
|
.then(showBalance)
|
||||||
|
|
|
@ -8,7 +8,6 @@ const solanaWeb3 = require('..');
|
||||||
|
|
||||||
const account1 = new solanaWeb3.Account();
|
const account1 = new solanaWeb3.Account();
|
||||||
const account2 = new solanaWeb3.Account();
|
const account2 = new solanaWeb3.Account();
|
||||||
const contractFunds = new solanaWeb3.Account();
|
|
||||||
const contractState = new solanaWeb3.Account();
|
const contractState = new solanaWeb3.Account();
|
||||||
|
|
||||||
const approver1 = new solanaWeb3.Account();
|
const approver1 = new solanaWeb3.Account();
|
||||||
|
@ -24,37 +23,34 @@ function showBalance() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
connection.getBalance(account1.publicKey),
|
connection.getBalance(account1.publicKey),
|
||||||
connection.getBalance(account2.publicKey),
|
connection.getBalance(account2.publicKey),
|
||||||
connection.getBalance(contractFunds.publicKey),
|
|
||||||
connection.getBalance(contractState.publicKey),
|
connection.getBalance(contractState.publicKey),
|
||||||
]).then(
|
]).then(([fromBalance, toBalance, contractStateBalance]) => {
|
||||||
([fromBalance, toBalance, contractFundsBalance, contractStateBalance]) => {
|
console.log(
|
||||||
console.log(
|
`Account1: ${account1.publicKey} has a balance of ${fromBalance}`,
|
||||||
`Account1: ${account1.publicKey} has a balance of ${fromBalance}`,
|
);
|
||||||
);
|
console.log(
|
||||||
console.log(
|
`Account2: ${account2.publicKey} has a balance of ${toBalance}`,
|
||||||
`Account2: ${account2.publicKey} has a balance of ${toBalance}`,
|
);
|
||||||
);
|
console.log(
|
||||||
console.log(
|
`Contract State: ${
|
||||||
`Contract Funds: ${
|
contractState.publicKey
|
||||||
contractFunds.publicKey
|
} has a balance of ${contractStateBalance}`,
|
||||||
} has a balance of ${contractFundsBalance}`,
|
);
|
||||||
);
|
});
|
||||||
console.log(
|
|
||||||
`Contract State: ${
|
|
||||||
contractState.publicKey
|
|
||||||
} has a balance of ${contractStateBalance}`,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirmTransaction(signature) {
|
function confirmTransaction(signature) {
|
||||||
console.log('Confirming transaction:', signature);
|
console.log('Confirming transaction:', signature);
|
||||||
return connection.getSignatureStatus(signature).then(confirmation => {
|
return connection.getSignatureStatus(signature).then(confirmation => {
|
||||||
if (confirmation !== 'Confirmed') {
|
if (confirmation && 'Ok' in confirmation) {
|
||||||
|
console.log('Transaction confirmed');
|
||||||
|
} else if (confirmation) {
|
||||||
|
throw new Error(
|
||||||
|
`Transaction was not confirmed (${JSON.stringify(confirmation.Err)})`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
throw new Error(`Transaction was not confirmed (${confirmation})`);
|
throw new Error(`Transaction was not confirmed (${confirmation})`);
|
||||||
}
|
}
|
||||||
console.log('Transaction confirmed');
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,43 +84,21 @@ showBalance()
|
||||||
})
|
})
|
||||||
.then(confirmTransaction)
|
.then(confirmTransaction)
|
||||||
.then(showBalance)
|
.then(showBalance)
|
||||||
.then(() => {
|
|
||||||
console.log(`\n== Creating account for the contract funds`);
|
|
||||||
const transaction = solanaWeb3.SystemProgram.createAccount(
|
|
||||||
account1.publicKey,
|
|
||||||
contractFunds.publicKey,
|
|
||||||
50, // number of lamports to transfer
|
|
||||||
0,
|
|
||||||
solanaWeb3.BudgetProgram.programId,
|
|
||||||
);
|
|
||||||
return connection.sendTransaction(transaction, account1);
|
|
||||||
})
|
|
||||||
.then(confirmTransaction)
|
|
||||||
.then(showBalance)
|
|
||||||
.then(() => {
|
|
||||||
console.log(`\n== Creating account for the contract state`);
|
|
||||||
const transaction = solanaWeb3.SystemProgram.createAccount(
|
|
||||||
account1.publicKey,
|
|
||||||
contractState.publicKey,
|
|
||||||
1, // account1 pays 1 lamport to hold the contract state
|
|
||||||
solanaWeb3.BudgetProgram.space,
|
|
||||||
solanaWeb3.BudgetProgram.programId,
|
|
||||||
);
|
|
||||||
return connection.sendTransaction(transaction, account1);
|
|
||||||
})
|
|
||||||
.then(confirmTransaction)
|
|
||||||
.then(showBalance)
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log(`\n== Initializing contract`);
|
console.log(`\n== Initializing contract`);
|
||||||
const transaction = solanaWeb3.BudgetProgram.payOnBoth(
|
const transaction = solanaWeb3.BudgetProgram.payOnBoth(
|
||||||
contractFunds.publicKey,
|
account1.publicKey,
|
||||||
contractState.publicKey,
|
contractState.publicKey,
|
||||||
account2.publicKey,
|
account2.publicKey,
|
||||||
50,
|
50,
|
||||||
solanaWeb3.BudgetProgram.signatureCondition(approver1.publicKey),
|
solanaWeb3.BudgetProgram.signatureCondition(approver1.publicKey),
|
||||||
solanaWeb3.BudgetProgram.signatureCondition(approver2.publicKey),
|
solanaWeb3.BudgetProgram.signatureCondition(approver2.publicKey),
|
||||||
);
|
);
|
||||||
return connection.sendTransaction(transaction, contractFunds);
|
return solanaWeb3.sendAndConfirmTransaction(
|
||||||
|
connection,
|
||||||
|
transaction,
|
||||||
|
account1,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.then(confirmTransaction)
|
.then(confirmTransaction)
|
||||||
.then(showBalance)
|
.then(showBalance)
|
||||||
|
@ -135,7 +109,11 @@ showBalance()
|
||||||
contractState.publicKey,
|
contractState.publicKey,
|
||||||
account2.publicKey,
|
account2.publicKey,
|
||||||
);
|
);
|
||||||
return connection.sendTransaction(transaction, approver1);
|
return solanaWeb3.sendAndConfirmTransaction(
|
||||||
|
connection,
|
||||||
|
transaction,
|
||||||
|
approver1,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.then(confirmTransaction)
|
.then(confirmTransaction)
|
||||||
.then(showBalance)
|
.then(showBalance)
|
||||||
|
@ -146,7 +124,11 @@ showBalance()
|
||||||
contractState.publicKey,
|
contractState.publicKey,
|
||||||
account2.publicKey,
|
account2.publicKey,
|
||||||
);
|
);
|
||||||
return connection.sendTransaction(transaction, approver2);
|
return solanaWeb3.sendAndConfirmTransaction(
|
||||||
|
connection,
|
||||||
|
transaction,
|
||||||
|
approver2,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.then(confirmTransaction)
|
.then(confirmTransaction)
|
||||||
.then(showBalance)
|
.then(showBalance)
|
||||||
|
|
|
@ -5851,7 +5851,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"marked": {
|
"marked": {
|
||||||
"version": "0.3.19",
|
"version": "0.3.19",
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
|
"resolved": "http://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
|
||||||
"integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==",
|
"integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
@ -6115,7 +6115,7 @@
|
||||||
},
|
},
|
||||||
"marked": {
|
"marked": {
|
||||||
"version": "0.3.19",
|
"version": "0.3.19",
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
|
"resolved": "http://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
|
||||||
"integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==",
|
"integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
@ -12399,7 +12399,7 @@
|
||||||
},
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
@ -16878,7 +16878,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as BufferLayout from 'buffer-layout';
|
||||||
|
|
||||||
import {Transaction} from './transaction';
|
import {Transaction} from './transaction';
|
||||||
import {PublicKey} from './publickey';
|
import {PublicKey} from './publickey';
|
||||||
import * as Layout from './layout';
|
import {SystemProgram} from './system-program';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a condition that is met by executing a `applySignature()`
|
* Represents a condition that is met by executing a `applySignature()`
|
||||||
|
@ -114,20 +114,10 @@ function serializeCondition(condition: BudgetCondition) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
case 'signature': {
|
case 'signature': {
|
||||||
const dataLayout = BufferLayout.struct([
|
|
||||||
BufferLayout.u32('condition'),
|
|
||||||
Layout.publicKey('from'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const from = condition.from.toBuffer();
|
const from = condition.from.toBuffer();
|
||||||
const data = Buffer.alloc(4 + from.length);
|
const data = Buffer.alloc(4 + from.length);
|
||||||
dataLayout.encode(
|
data.writeUInt32LE(1, 0); // Condition enum = Signature
|
||||||
{
|
from.copy(data, 4);
|
||||||
instruction: 1, // Signature
|
|
||||||
from,
|
|
||||||
},
|
|
||||||
data,
|
|
||||||
);
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -190,8 +180,8 @@ export class BudgetProgram {
|
||||||
pos += 4;
|
pos += 4;
|
||||||
|
|
||||||
switch (conditions.length) {
|
switch (conditions.length) {
|
||||||
case 0:
|
case 0: {
|
||||||
data.writeUInt32LE(0, pos); // Budget enum = Pay
|
data.writeUInt32LE(0, pos); // BudgetExpr enum = Pay
|
||||||
pos += 4;
|
pos += 4;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -199,17 +189,27 @@ export class BudgetProgram {
|
||||||
payment.copy(data, pos);
|
payment.copy(data, pos);
|
||||||
pos += payment.length;
|
pos += payment.length;
|
||||||
}
|
}
|
||||||
|
const trimmedData = data.slice(0, pos);
|
||||||
|
|
||||||
return new Transaction().add({
|
const transaction = SystemProgram.createAccount(
|
||||||
|
from,
|
||||||
|
program,
|
||||||
|
amount,
|
||||||
|
trimmedData.length,
|
||||||
|
this.programId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return transaction.add({
|
||||||
keys: [
|
keys: [
|
||||||
{pubkey: from, isSigner: true, isDebitable: true},
|
|
||||||
{pubkey: to, isSigner: false, isDebitable: false},
|
{pubkey: to, isSigner: false, isDebitable: false},
|
||||||
|
{pubkey: program, isSigner: false, isDebitable: true},
|
||||||
],
|
],
|
||||||
programId: this.programId,
|
programId: this.programId,
|
||||||
data: data.slice(0, pos),
|
data: trimmedData,
|
||||||
});
|
});
|
||||||
case 1:
|
}
|
||||||
data.writeUInt32LE(1, pos); // Budget enum = After
|
case 1: {
|
||||||
|
data.writeUInt32LE(1, pos); // BudgetExpr enum = After
|
||||||
pos += 4;
|
pos += 4;
|
||||||
{
|
{
|
||||||
const condition = conditions[0];
|
const condition = conditions[0];
|
||||||
|
@ -218,23 +218,32 @@ export class BudgetProgram {
|
||||||
conditionData.copy(data, pos);
|
conditionData.copy(data, pos);
|
||||||
pos += conditionData.length;
|
pos += conditionData.length;
|
||||||
|
|
||||||
|
data.writeUInt32LE(0, pos); // BudgetExpr enum = Pay
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
const paymentData = serializePayment({amount, to});
|
const paymentData = serializePayment({amount, to});
|
||||||
paymentData.copy(data, pos);
|
paymentData.copy(data, pos);
|
||||||
pos += paymentData.length;
|
pos += paymentData.length;
|
||||||
}
|
}
|
||||||
|
const trimmedData = data.slice(0, pos);
|
||||||
|
|
||||||
return new Transaction().add({
|
const transaction = SystemProgram.createAccount(
|
||||||
keys: [
|
from,
|
||||||
{pubkey: from, isSigner: true, isDebitable: true},
|
program,
|
||||||
{pubkey: program, isSigner: false, isDebitable: true},
|
amount,
|
||||||
{pubkey: to, isSigner: false, isDebitable: false},
|
trimmedData.length,
|
||||||
],
|
this.programId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return transaction.add({
|
||||||
|
keys: [{pubkey: program, isSigner: false, isDebitable: true}],
|
||||||
programId: this.programId,
|
programId: this.programId,
|
||||||
data: data.slice(0, pos),
|
data: trimmedData,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
case 2:
|
case 2: {
|
||||||
data.writeUInt32LE(2, pos); // Budget enum = Or
|
data.writeUInt32LE(2, pos); // BudgetExpr enum = Or
|
||||||
pos += 4;
|
pos += 4;
|
||||||
|
|
||||||
for (let condition of conditions) {
|
for (let condition of conditions) {
|
||||||
|
@ -242,20 +251,29 @@ export class BudgetProgram {
|
||||||
conditionData.copy(data, pos);
|
conditionData.copy(data, pos);
|
||||||
pos += conditionData.length;
|
pos += conditionData.length;
|
||||||
|
|
||||||
|
data.writeUInt32LE(0, pos); // BudgetExpr enum = Pay
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
const paymentData = serializePayment({amount, to});
|
const paymentData = serializePayment({amount, to});
|
||||||
paymentData.copy(data, pos);
|
paymentData.copy(data, pos);
|
||||||
pos += paymentData.length;
|
pos += paymentData.length;
|
||||||
}
|
}
|
||||||
|
const trimmedData = data.slice(0, pos);
|
||||||
|
|
||||||
return new Transaction().add({
|
const transaction = SystemProgram.createAccount(
|
||||||
keys: [
|
from,
|
||||||
{pubkey: from, isSigner: true, isDebitable: true},
|
program,
|
||||||
{pubkey: program, isSigner: false, isDebitable: true},
|
amount,
|
||||||
{pubkey: to, isSigner: false, isDebitable: false},
|
trimmedData.length,
|
||||||
],
|
this.programId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return transaction.add({
|
||||||
|
keys: [{pubkey: program, isSigner: false, isDebitable: true}],
|
||||||
programId: this.programId,
|
programId: this.programId,
|
||||||
data: data.slice(0, pos),
|
data: trimmedData,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -282,7 +300,7 @@ export class BudgetProgram {
|
||||||
data.writeUInt32LE(0, pos); // NewBudget instruction
|
data.writeUInt32LE(0, pos); // NewBudget instruction
|
||||||
pos += 4;
|
pos += 4;
|
||||||
|
|
||||||
data.writeUInt32LE(3, pos); // Budget enum = And
|
data.writeUInt32LE(3, pos); // BudgetExpr enum = And
|
||||||
pos += 4;
|
pos += 4;
|
||||||
|
|
||||||
for (let condition of [condition1, condition2]) {
|
for (let condition of [condition1, condition2]) {
|
||||||
|
@ -291,18 +309,27 @@ export class BudgetProgram {
|
||||||
pos += conditionData.length;
|
pos += conditionData.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.writeUInt32LE(0, pos); // BudgetExpr enum = Pay
|
||||||
|
pos += 4;
|
||||||
|
|
||||||
const paymentData = serializePayment({amount, to});
|
const paymentData = serializePayment({amount, to});
|
||||||
paymentData.copy(data, pos);
|
paymentData.copy(data, pos);
|
||||||
pos += paymentData.length;
|
pos += paymentData.length;
|
||||||
|
|
||||||
return new Transaction().add({
|
const trimmedData = data.slice(0, pos);
|
||||||
keys: [
|
|
||||||
{pubkey: from, isSigner: true, isDebitable: true},
|
const transaction = SystemProgram.createAccount(
|
||||||
{pubkey: program, isSigner: false, isDebitable: true},
|
from,
|
||||||
{pubkey: to, isSigner: false, isDebitable: false},
|
program,
|
||||||
],
|
amount,
|
||||||
|
trimmedData.length,
|
||||||
|
this.programId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return transaction.add({
|
||||||
|
keys: [{pubkey: program, isSigner: false, isDebitable: true}],
|
||||||
programId: this.programId,
|
programId: this.programId,
|
||||||
data: data.slice(0, pos),
|
data: trimmedData,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,8 @@ export class Transaction {
|
||||||
let numCreditOnlySignedAccounts = 0;
|
let numCreditOnlySignedAccounts = 0;
|
||||||
let numCreditOnlyUnsignedAccounts = 0;
|
let numCreditOnlyUnsignedAccounts = 0;
|
||||||
|
|
||||||
|
const programIds = [];
|
||||||
|
|
||||||
this.instructions.forEach(instruction => {
|
this.instructions.forEach(instruction => {
|
||||||
instruction.keys.forEach(keySignerPair => {
|
instruction.keys.forEach(keySignerPair => {
|
||||||
const keyStr = keySignerPair.pubkey.toString();
|
const keyStr = keySignerPair.pubkey.toString();
|
||||||
|
@ -183,6 +185,12 @@ export class Transaction {
|
||||||
});
|
});
|
||||||
|
|
||||||
const programId = instruction.programId.toString();
|
const programId = instruction.programId.toString();
|
||||||
|
if (!programIds.includes(programId)) {
|
||||||
|
programIds.push(programId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
programIds.forEach(programId => {
|
||||||
if (!keys.includes(programId)) {
|
if (!keys.includes(programId)) {
|
||||||
keys.push(programId);
|
keys.push(programId);
|
||||||
numCreditOnlyUnsignedAccounts += 1;
|
numCreditOnlyUnsignedAccounts += 1;
|
||||||
|
|
|
@ -15,7 +15,8 @@ test('pay', () => {
|
||||||
to.publicKey,
|
to.publicKey,
|
||||||
123,
|
123,
|
||||||
);
|
);
|
||||||
expect(transaction.keys).toHaveLength(2);
|
expect(transaction.instructions[0].keys).toHaveLength(2);
|
||||||
|
expect(transaction.instructions[1].keys).toHaveLength(2);
|
||||||
// TODO: Validate transaction contents more
|
// TODO: Validate transaction contents more
|
||||||
|
|
||||||
transaction = BudgetProgram.pay(
|
transaction = BudgetProgram.pay(
|
||||||
|
@ -25,7 +26,8 @@ test('pay', () => {
|
||||||
123,
|
123,
|
||||||
BudgetProgram.signatureCondition(from.publicKey),
|
BudgetProgram.signatureCondition(from.publicKey),
|
||||||
);
|
);
|
||||||
expect(transaction.keys).toHaveLength(3);
|
expect(transaction.instructions[0].keys).toHaveLength(2);
|
||||||
|
expect(transaction.instructions[1].keys).toHaveLength(1);
|
||||||
// TODO: Validate transaction contents more
|
// TODO: Validate transaction contents more
|
||||||
|
|
||||||
transaction = BudgetProgram.pay(
|
transaction = BudgetProgram.pay(
|
||||||
|
@ -36,7 +38,8 @@ test('pay', () => {
|
||||||
BudgetProgram.signatureCondition(from.publicKey),
|
BudgetProgram.signatureCondition(from.publicKey),
|
||||||
BudgetProgram.timestampCondition(from.publicKey, new Date()),
|
BudgetProgram.timestampCondition(from.publicKey, new Date()),
|
||||||
);
|
);
|
||||||
expect(transaction.keys).toHaveLength(3);
|
expect(transaction.instructions[0].keys).toHaveLength(2);
|
||||||
|
expect(transaction.instructions[1].keys).toHaveLength(1);
|
||||||
// TODO: Validate transaction contents more
|
// TODO: Validate transaction contents more
|
||||||
|
|
||||||
transaction = BudgetProgram.payOnBoth(
|
transaction = BudgetProgram.payOnBoth(
|
||||||
|
@ -47,7 +50,8 @@ test('pay', () => {
|
||||||
BudgetProgram.signatureCondition(from.publicKey),
|
BudgetProgram.signatureCondition(from.publicKey),
|
||||||
BudgetProgram.timestampCondition(from.publicKey, new Date()),
|
BudgetProgram.timestampCondition(from.publicKey, new Date()),
|
||||||
);
|
);
|
||||||
expect(transaction.keys).toHaveLength(3);
|
expect(transaction.instructions[0].keys).toHaveLength(2);
|
||||||
|
expect(transaction.instructions[1].keys).toHaveLength(1);
|
||||||
// TODO: Validate transaction contents more
|
// TODO: Validate transaction contents more
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue