Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: replace bip39 with @scure/bip39 #3121

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
348 changes: 186 additions & 162 deletions integration-tests/__tests__/sapling/sapling-batched-transactions.spec.ts

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,115 +1,144 @@
import { ContractAbstraction, ContractProvider, RpcReadAdapter } from '@taquito/taquito';
import {
ContractAbstraction,
ContractProvider,
RpcReadAdapter,
} from '@taquito/taquito';
import { CONFIGS } from '../../config';
import { InMemorySpendingKey, SaplingToolkit, InMemoryProvingKey } from '@taquito/sapling';
import {
InMemorySpendingKey,
SaplingToolkit,
InMemoryProvingKey,
} from '@taquito/sapling';
import BigNumber from 'bignumber.js';
import { singleSaplingStateContractJProtocol } from '../../data/single_sapling_state_contract_jakarta_michelson';
import * as bip39 from 'bip39';
import * as bip39 from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english';

CONFIGS().forEach(({ lib, rpc, setup }) => {
const Tezos = lib;
let saplingContract: ContractAbstraction<ContractProvider>;
let bobInmemorySpendingKey: InMemorySpendingKey;
let bobPaymentAddress: string
let bobPaymentAddress: string;
let aliceInMemorySpendingKey: InMemorySpendingKey;
let aliceInMemoryProvingKey: InMemoryProvingKey;
let alicePaymentAddress: string;
const tezosAddress = 'tz2TSvNTh2epDMhZHrw73nV9piBX7kLZ9K9m';
const memoSize = 8;

describe(`Test producing proofs with a proving key rather than a spending key: ${rpc}`, () => {

beforeAll(async () => {
await setup();

// Deploy the sapling contract
const saplingContractOrigination = await Tezos.contract.originate({
code: singleSaplingStateContractJProtocol(),
init: '{}'
init: '{}',
});
await saplingContractOrigination.confirmation();
saplingContract = await saplingContractOrigination.contract();

// Generate a spending key and an InMemorySpendingKey instance for Bob using a mnemonic
const mnemonic: string = bip39.generateMnemonic();
const mnemonic: string = bip39.generateMnemonic(wordlist);
bobInmemorySpendingKey = await InMemorySpendingKey.fromMnemonic(mnemonic);

// Instantiate an InMemorySpendingKey from a spending key for Alice
aliceInMemorySpendingKey = new InMemorySpendingKey('sask27SLmU9herddHz4qFJBLMjWYMbJF8RtS579w9ej9mfCYK7VUdyCJPHK8AzW9zMsopGZEkYeNjAY7Zz1bkM7CGu8eKLzrjBLTMC5wWJDhxiK91ahA29rhDRsHdJDV2u2jFwb2MNUix8JW7sAkAqYVaJpCehTBPgRQ1KqKwqqUaNmuD8kazd4Q8MCWmgbWs21Yuomdqyi9FLigjRp7oY4m5adaVU19Nj1AHvsMY2tePeU2L')
aliceInMemoryProvingKey = new InMemoryProvingKey('44259fd700dc80120d3c9ca65d698f6064043b048b079caa4f198aed962717403f80bf8cb9a8da8deb290913e9302be00c56f4565d917a6170be1880f42bb709');

aliceInMemorySpendingKey = new InMemorySpendingKey(
'sask27SLmU9herddHz4qFJBLMjWYMbJF8RtS579w9ej9mfCYK7VUdyCJPHK8AzW9zMsopGZEkYeNjAY7Zz1bkM7CGu8eKLzrjBLTMC5wWJDhxiK91ahA29rhDRsHdJDV2u2jFwb2MNUix8JW7sAkAqYVaJpCehTBPgRQ1KqKwqqUaNmuD8kazd4Q8MCWmgbWs21Yuomdqyi9FLigjRp7oY4m5adaVU19Nj1AHvsMY2tePeU2L'
);
aliceInMemoryProvingKey = new InMemoryProvingKey(
'44259fd700dc80120d3c9ca65d698f6064043b048b079caa4f198aed962717403f80bf8cb9a8da8deb290913e9302be00c56f4565d917a6170be1880f42bb709'
);
});

it('Verify that Alice can shield tokens', async () => {

const amountToAlice = 3;
const aliceSaplingToolkit = new SaplingToolkit(
{ saplingSigner: aliceInMemorySpendingKey, saplingProver: aliceInMemoryProvingKey },
{
saplingSigner: aliceInMemorySpendingKey,
saplingProver: aliceInMemoryProvingKey,
},
{ contractAddress: saplingContract.address, memoSize },
new RpcReadAdapter(Tezos.rpc)
);
const aliceInMemoryViewingKey = await aliceInMemorySpendingKey.getSaplingViewingKeyProvider();
const aliceInMemoryViewingKey =
await aliceInMemorySpendingKey.getSaplingViewingKeyProvider();
// Fetch a payment address (zet) for Alice
alicePaymentAddress = (await aliceInMemoryViewingKey.getAddress()).address;
alicePaymentAddress = (await aliceInMemoryViewingKey.getAddress())
.address;

const shieldedTx = await aliceSaplingToolkit.prepareShieldedTransaction([{
to: alicePaymentAddress,
amount: amountToAlice,
memo: 'First Tx'
}])
const shieldedTx = await aliceSaplingToolkit.prepareShieldedTransaction([
{
to: alicePaymentAddress,
amount: amountToAlice,
memo: 'First Tx',
},
]);

// Inject the sapling transaction using the ContractAbstraction by calling the default entrypoint
// The amount MUST be specified in the send method in order to transfer the 3 tez to the shielded pool
const op = await saplingContract.methods.default([shieldedTx]).send({ amount: amountToAlice });
const op = await saplingContract.methods
.default([shieldedTx])
.send({ amount: amountToAlice });
await op.confirmation();

expect(op.status).toEqual('applied');
expect(op.hash).toBeDefined();
expect(op.includedInBlock).toBeLessThan(Number.POSITIVE_INFINITY);

});

it("Verify that Alice's balance in the sapling pool updated after the shielded tx", async () => {
const aliceSaplingToolkit = new SaplingToolkit(
{ saplingSigner: aliceInMemorySpendingKey, saplingProver: aliceInMemoryProvingKey },
{
saplingSigner: aliceInMemorySpendingKey,
saplingProver: aliceInMemoryProvingKey,
},
{ contractAddress: saplingContract.address, memoSize },
new RpcReadAdapter(Tezos.rpc)
);
const aliceTxViewer = await aliceSaplingToolkit.getSaplingTransactionViewer();
const aliceTxViewer =
await aliceSaplingToolkit.getSaplingTransactionViewer();
const aliceBalance = await aliceTxViewer.getBalance();

// The returned balance is in MUTEZ
expect(aliceBalance).toEqual(new BigNumber(3000000));

const inputsAlice = await aliceTxViewer.getIncomingAndOutgoingTransactions();
const inputsAlice =
await aliceTxViewer.getIncomingAndOutgoingTransactions();
expect(inputsAlice).toEqual({
incoming: [
{
value: new BigNumber(3000000),
memo: 'First Tx',
paymentAddress: alicePaymentAddress,
isSpent: false
}
isSpent: false,
},
],
outgoing: []
})
outgoing: [],
});
});

it('Verify that Alice can do a shielded transaction to Bob', async () => {
const amountToBob = 2;
// Bob needs to give a payment address (zet) to Alice
const bobInMemoryViewingKey = await bobInmemorySpendingKey.getSaplingViewingKeyProvider();
const bobInMemoryViewingKey =
await bobInmemorySpendingKey.getSaplingViewingKeyProvider();
bobPaymentAddress = (await bobInMemoryViewingKey.getAddress()).address;

const aliceSaplingToolkit = new SaplingToolkit(
{ saplingSigner: aliceInMemorySpendingKey, saplingProver: aliceInMemoryProvingKey },
{
saplingSigner: aliceInMemorySpendingKey,
saplingProver: aliceInMemoryProvingKey,
},
{ contractAddress: saplingContract.address, memoSize },
new RpcReadAdapter(Tezos.rpc)
);
const tx = await aliceSaplingToolkit.prepareSaplingTransaction([{
to: bobPaymentAddress,
amount: amountToBob,
memo: 'A gift'
}])
const tx = await aliceSaplingToolkit.prepareSaplingTransaction([
{
to: bobPaymentAddress,
amount: amountToBob,
memo: 'A gift',
},
]);

// Inject the sapling transaction using the ContractAbstraction by calling the default entrypoint
const op = await saplingContract.methods.default([tx]).send();
@@ -118,53 +147,63 @@ CONFIGS().forEach(({ lib, rpc, setup }) => {
expect(op.status).toEqual('applied');
expect(op.hash).toBeDefined();
expect(op.includedInBlock).toBeLessThan(Number.POSITIVE_INFINITY);

});

it("Verify that Alice's balance in the sapling pool updated after the sapling tx", async () => {
const aliceSaplingToolkit = new SaplingToolkit(
{ saplingSigner: aliceInMemorySpendingKey, saplingProver: aliceInMemoryProvingKey },
{
saplingSigner: aliceInMemorySpendingKey,
saplingProver: aliceInMemoryProvingKey,
},
{ contractAddress: saplingContract.address, memoSize },
new RpcReadAdapter(Tezos.rpc)
);
const aliceTxViewer = await aliceSaplingToolkit.getSaplingTransactionViewer();
const aliceTxViewer =
await aliceSaplingToolkit.getSaplingTransactionViewer();
const aliceBalance = await aliceTxViewer.getBalance();

// The returned balance is in MUTEZ
expect(aliceBalance).toEqual(new BigNumber(1000000));

const inputsAlice = await aliceTxViewer.getIncomingAndOutgoingTransactions();
const inputsAlice =
await aliceTxViewer.getIncomingAndOutgoingTransactions();
expect(inputsAlice).toEqual({
incoming: [
{
value: new BigNumber(3000000),
memo: 'First Tx',
paymentAddress: alicePaymentAddress,
isSpent: true
isSpent: true,
},
{ // This input is a payback for when Alice sent 2 tz to bob (3tz - 2tz = 1tz).
{
// This input is a payback for when Alice sent 2 tz to bob (3tz - 2tz = 1tz).
// Alice consumed the 3tz input and received 1tz back.
value: new BigNumber(1000000),
memo: '',
paymentAddress: alicePaymentAddress,
isSpent: false
}
isSpent: false,
},
],
outgoing: [
{
value: new BigNumber(2000000),
memo: 'A gift',
paymentAddress: bobPaymentAddress
paymentAddress: bobPaymentAddress,
},
{ // Here Alice sent 1tz back to her (matching the payback input above).
{
// Here Alice sent 1tz back to her (matching the payback input above).
value: new BigNumber(1000000),
memo: '',
paymentAddress: alicePaymentAddress
}
]
})
paymentAddress: alicePaymentAddress,
},
],
});

const bobSaplingToolkit = new SaplingToolkit({ saplingSigner: bobInmemorySpendingKey }, { contractAddress: saplingContract.address, memoSize }, new RpcReadAdapter(Tezos.rpc))
const bobSaplingToolkit = new SaplingToolkit(
{ saplingSigner: bobInmemorySpendingKey },
{ contractAddress: saplingContract.address, memoSize },
new RpcReadAdapter(Tezos.rpc)
);
const bobTxViewer = await bobSaplingToolkit.getSaplingTransactionViewer();
const bobBalance = await bobTxViewer.getBalance();

@@ -178,27 +217,30 @@ CONFIGS().forEach(({ lib, rpc, setup }) => {
value: new BigNumber(2000000),
memo: 'A gift',
paymentAddress: bobPaymentAddress,
isSpent: false
}
isSpent: false,
},
],
outgoing: []
})
outgoing: [],
});
});

it('Verify that Alice can unshield tokens', async () => {

const amount = 1;
const aliceSaplingToolkit = new SaplingToolkit(
{ saplingSigner: aliceInMemorySpendingKey, saplingProver: aliceInMemoryProvingKey },
{
saplingSigner: aliceInMemorySpendingKey,
saplingProver: aliceInMemoryProvingKey,
},
{ contractAddress: saplingContract.address, memoSize },
new RpcReadAdapter(Tezos.rpc)
);
const tezosInitialBalance = await Tezos.tz.getBalance(tezosAddress);

const unshieldedTx = await aliceSaplingToolkit.prepareUnshieldedTransaction({
to: tezosAddress,
amount
})
const unshieldedTx =
await aliceSaplingToolkit.prepareUnshieldedTransaction({
to: tezosAddress,
amount,
});

// Inject the sapling transaction using the ContractAbstraction by calling the default entrypoint
const op = await saplingContract.methods.default([unshieldedTx]).send();
@@ -209,63 +251,67 @@ CONFIGS().forEach(({ lib, rpc, setup }) => {
expect(op.includedInBlock).toBeLessThan(Number.POSITIVE_INFINITY);

const tezosUpdatedBalance = await Tezos.tz.getBalance(tezosAddress);
expect(tezosUpdatedBalance).toEqual(tezosInitialBalance.plus(new BigNumber(1000000)));

expect(tezosUpdatedBalance).toEqual(
tezosInitialBalance.plus(new BigNumber(1000000))
);
});

it("Verify that Alice's balance in the sapling pool updated after the unshielded tx", async () => {
const aliceSaplingToolkit = new SaplingToolkit(
{ saplingSigner: aliceInMemorySpendingKey, saplingProver: aliceInMemoryProvingKey },
{
saplingSigner: aliceInMemorySpendingKey,
saplingProver: aliceInMemoryProvingKey,
},
{ contractAddress: saplingContract.address, memoSize },
new RpcReadAdapter(Tezos.rpc)
);
const aliceTxViewer = await aliceSaplingToolkit.getSaplingTransactionViewer();
const aliceTxViewer =
await aliceSaplingToolkit.getSaplingTransactionViewer();
const aliceBalance = await aliceTxViewer.getBalance();

expect(aliceBalance).toEqual(new BigNumber(0));

const inputsAlice = await aliceTxViewer.getIncomingAndOutgoingTransactions();
const inputsAlice =
await aliceTxViewer.getIncomingAndOutgoingTransactions();
expect(inputsAlice).toEqual({
incoming: [
{
value: new BigNumber(3000000),
memo: 'First Tx',
paymentAddress: alicePaymentAddress,
isSpent: true
isSpent: true,
},
{
value: new BigNumber(1000000),
memo: '',
paymentAddress: alicePaymentAddress,
isSpent: true
isSpent: true,
},
{
value: new BigNumber(0),
memo: '',
paymentAddress: alicePaymentAddress,
isSpent: false
}
isSpent: false,
},
],
outgoing: [
{
value: new BigNumber(2000000),
memo: 'A gift',
paymentAddress: bobPaymentAddress
paymentAddress: bobPaymentAddress,
},
{
value: new BigNumber(1000000),
memo: '',
paymentAddress: alicePaymentAddress
paymentAddress: alicePaymentAddress,
},
{
value: new BigNumber(0),
memo: '',
paymentAddress: alicePaymentAddress
}
]
})

paymentAddress: alicePaymentAddress,
},
],
});
});

});
});
Loading