Skip to content
Merged
Show file tree
Hide file tree
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
5 changes: 3 additions & 2 deletions modules/sdk-coin-xtz/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@
"@bitgo/secp256k1": "^1.7.0",
"@bitgo/statics": "^58.8.0",
"@noble/curves": "1.8.1",
"@taquito/local-forging": "6.3.5-beta.0",
"@taquito/signer": "6.3.5-beta.0",
"@taquito/local-forging": "^23.0.2",
"@taquito/rpc": "^23.0.2",
"@taquito/signer": "^23.0.2",
"bignumber.js": "^9.0.0",
"bs58check": "^2.1.2",
"libsodium-wrappers": "^0.7.6",
Expand Down
3 changes: 2 additions & 1 deletion modules/sdk-coin-xtz/src/lib/iface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
TransactionRecipient as Recipient,
TransactionPrebuild as BaseTransactionPrebuild,
} from '@bitgo/sdk-core';
import { OperationContents } from '@taquito/rpc';

export interface XtzSignTransactionOptions extends SignTransactionOptions {
txPrebuild: TransactionPrebuild;
Expand Down Expand Up @@ -79,7 +80,7 @@ export interface TransactionOp extends Operation {

export interface ParsedTransaction {
branch: string;
contents: Operation[];
contents: OperationContents[];
}

/**
Expand Down
29 changes: 16 additions & 13 deletions modules/sdk-coin-xtz/src/lib/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
TransactionType,
} from '@bitgo/sdk-core';
import { BaseCoin as CoinConfig } from '@bitgo/statics';
import { CODEC, localForger } from '@taquito/local-forging';
import { localForger } from '@taquito/local-forging';
import { OpKind } from '@taquito/rpc';
import BigNumber from 'bignumber.js';
import { IndexedSignature, OriginationOp, ParsedTransaction, RevealOp, TransactionOp } from './iface';
import { KeyPair } from './keyPair';
Expand Down Expand Up @@ -77,8 +78,6 @@ export class Transaction extends BaseTransaction {
this._encodedTransaction = await localForger.forge(parsedTransaction);
}
if (transactionId) {
// If the transaction id is passed, save it and clean up the entries since they will be
// recalculated
this._id = transactionId;
this._inputs = [];
this._outputs = [];
Expand All @@ -88,26 +87,30 @@ export class Transaction extends BaseTransaction {
this._parsedTransaction = parsedTransaction;
let operationIndex = 0;
for (const operation of parsedTransaction.contents) {
if (this._source && this._source !== operation.source) {
throw new InvalidTransactionError(
'Source must be the same for every operation but it changed from ' + this._source + ' to ' + operation.source
);
} else {
this._source = operation.source;
// Narrowing: only operations with a source have a source field
if ('source' in operation) {
if (this._source && this._source !== operation.source) {
throw new InvalidTransactionError(
`Source must be the same for every operation but it changed from ${this._source} to ${operation.source}`
);
} else {
this._source = operation.source;
}
}

switch (operation.kind) {
case CODEC.OP_ORIGINATION:
case OpKind.ORIGINATION:
await this.recordOriginationOpFields(operation as OriginationOp, operationIndex);
operationIndex++;
break;
case CODEC.OP_REVEAL:
case OpKind.REVEAL:
this.recordRevealOpFields(operation as RevealOp);
break;
case CODEC.OP_TRANSACTION:
case OpKind.TRANSACTION:
this.recordTransactionOpFields(operation as TransactionOp);
break;
default:
break;
break; // skip operations like attestations, endorsements, etc.
}
}
}
Expand Down
21 changes: 11 additions & 10 deletions modules/sdk-coin-xtz/src/lib/transactionBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { BaseKey, BuildTransactionError, SigningError, BaseTransactionBuilder, T
import { BaseCoin as CoinConfig } from '@bitgo/statics';
import BigNumber from 'bignumber.js';
import { Address } from './address';
import { Fee, IndexedData, IndexedSignature, Key, Operation, OriginationOp, RevealOp, TransactionOp } from './iface';
import { Fee, IndexedData, IndexedSignature, Key, OriginationOp, RevealOp, TransactionOp } from './iface';
import { OperationContents } from '@taquito/rpc';
import { KeyPair } from './keyPair';
import {
forwarderOriginationOperation,
Expand Down Expand Up @@ -149,34 +150,34 @@ export class TransactionBuilder extends BaseTransactionBuilder {
}
// TODO: make changes to the transaction if any extra parameter has been set then sign it
} else {
let contents: Operation[] = [];
let contents: OperationContents[] = [];
switch (this._type) {
case TransactionType.AccountUpdate:
if (this._publicKeyToReveal) {
contents.push(this.buildPublicKeyRevelationOperation());
contents.push(this.buildPublicKeyRevelationOperation() as OperationContents);
}
break;
case TransactionType.WalletInitialization:
if (this._publicKeyToReveal) {
contents.push(this.buildPublicKeyRevelationOperation());
contents.push(this.buildPublicKeyRevelationOperation() as OperationContents);
}
contents.push(this.buildWalletInitializationOperations());
contents.push(this.buildWalletInitializationOperations() as OperationContents);
break;
case TransactionType.Send:
if (this._publicKeyToReveal) {
contents.push(this.buildPublicKeyRevelationOperation());
contents.push(this.buildPublicKeyRevelationOperation() as OperationContents);
}
contents = contents.concat(await this.buildSendTransactionContent());
contents = contents.concat((await this.buildSendTransactionContent()) as OperationContents[]);
break;
case TransactionType.AddressInitialization:
if (this._publicKeyToReveal) {
contents.push(this.buildPublicKeyRevelationOperation());
contents.push(this.buildPublicKeyRevelationOperation() as OperationContents);
}
contents = contents.concat(this.buildForwarderDeploymentContent());
contents.push(this.buildForwarderDeploymentContent() as OperationContents);
break;
case TransactionType.SingleSigSend:
// No support for revelation txns as primary use case is to send from fee address
contents = contents.concat(await this.buildSendTransactionContent());
contents = contents.concat((await this.buildSendTransactionContent()) as OperationContents[]);
break;
default:
throw new BuildTransactionError('Unsupported transaction type');
Expand Down
10 changes: 5 additions & 5 deletions modules/sdk-coin-xtz/test/unit/offlineTransactionBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ describe('Offline Tezos Transaction builder', function () {
offlineTxBuilder.sign({ key: defaultKeyPair.getKeys().prv });
const signedTx = await offlineTxBuilder.build();

signedTx.id.should.equal('oomXs6PuWtmGwMKoXTNsu9XJHnGXtuRujcHMeYS9y37Xj6sXPHb');
signedTx.id.should.equal('oos4n1zJAGeqLQrNsnGAfzzj6FeZqbSrnAMVTdC485cinFWN6su');
signedTx.type.should.equal(TransactionType.AccountUpdate);
signedTx.source.should.equal('tz2PtJ9zgEgFVTRqy6GXsst54tH3ksEnYvvS');
should.equal(signedTx.inputs.length, 1);
Expand All @@ -114,7 +114,7 @@ describe('Offline Tezos Transaction builder', function () {
signedTx.inputs[0].value.should.equal('1420');
signedTx.signature.length.should.equal(1);
signedTx.signature[0].should.equal(
'sigQyYsfhtrJBKZuJSEizDdxoejNVvJWRZPDMWdpXVvdTVix37HzURwXfXsi9METnRzskvjgsBSgiF4pr7RVxzWLuixxJL8U'
'sigTtfcxtvU5zWbsWDJwKvHdDcWYDhgsb9ozmQ44AUGHnSJJgvPR2CvNCUX8axezJKoZRzgv9gSE3GSDh5SEbm31JqM53yyg'
);
});

Expand Down Expand Up @@ -310,9 +310,9 @@ describe('Offline Tezos Transaction builder', function () {
});

should.exist(consolidationResult);
consolidationResult.id.should.equal('opNrMMvnmQ6cE9JqRD8g14B6XfwGEUs7L9Bgn9qEkTtLeFEX9Tk');
consolidationResult.id.should.equal('op22ZtxX7ZsogUuMdvwuMCS6tegJXV8FKsAjzoWAt3JwibBV2A5');
consolidationResult.tx.should.equal(
'ed8f6833f4db890c1f923d51074aa7b3982f7281f42da80212b819ad68c223776b01c62f80a80ce748a8b5ffcf97004b9807cb59b0b78c0bc1f5851ae852000102e8c94e3e18d8a493a2f0baa81eb0ab7fac5d23fe672f9133048ebc8cccc6f5066c01c62f80a80ce748a8b5ffcf97004b9807cb59b0b798f402c2f5851af02eac020001bda70b50cf607aee95c10322a8bff9fc4df50f8500ffff046d61696e0000005f070707070081eb8b34050502000000440320053d036d0743035d0100000024747a3252746e76454c564157356455547473424e47366362534132655146695974345270031e0743036a009482fd11034f034d031b020000000603060306030661836db09de792bfba0cb422fbb61c77b77fd80e22386cc9d7380fb7da67347f594bd8d809bfaf3d1ff172b329263ac1ad9ef2e3eacf1a199f918e33c2bd4adb'
'ed8f6833f4db890c1f923d51074aa7b3982f7281f42da80212b819ad68c223776b01c62f80a80ce748a8b5ffcf97004b9807cb59b0b78c0bc1f5851ae852000102e8c94e3e18d8a493a2f0baa81eb0ab7fac5d23fe672f9133048ebc8cccc6f506006c01c62f80a80ce748a8b5ffcf97004b9807cb59b0b798f402c2f5851af02eac020001bda70b50cf607aee95c10322a8bff9fc4df50f8500ffff046d61696e0000005f070707070081eb8b34050502000000440320053d036d0743035d0100000024747a3252746e76454c564157356455547473424e47366362534132655146695974345270031e0743036a009482fd11034f034d031b0200000006030603060306e13e1be168af9539e0b7cb89689ce734bae6fcf3bed1a5a60749ce3bcd8864ea4c2623a0989f5de75c935746e3c88c9caab821876a060019e70f385bf3af4548'
);
});

Expand Down Expand Up @@ -345,7 +345,7 @@ describe('Offline Tezos Transaction builder', function () {

should.exist(consolidationResult);
consolidationResult.txHex.should.equal(
'ed8f6833f4db890c1f923d51074aa7b3982f7281f42da80212b819ad68c223776b01b6da9737d1b4b75053a387d9122c22598ead2d3d8c0bcfda9c1ae852000102f1eb6b09e45afffb3aca4215637edf54d2ea3c4491726128ce5a6071a57dac0e6c01b6da9737d1b4b75053a387d9122c22598ead2d3d98f402d0da9c1af02eac020001ea4d295f3387e9efbf6d791475cb936839eb8d5800ffff046d61696e0000005e07070707008fb5b934050502000000430320053d036d0743035d0100000024747a3252746e76454c564157356455547473424e47366362534132655146695974345270031e0743036a0080897a034f034d031b0200000006030603060306'
'ed8f6833f4db890c1f923d51074aa7b3982f7281f42da80212b819ad68c223776b01b6da9737d1b4b75053a387d9122c22598ead2d3d8c0bcfda9c1ae852000102f1eb6b09e45afffb3aca4215637edf54d2ea3c4491726128ce5a6071a57dac0e006c01b6da9737d1b4b75053a387d9122c22598ead2d3d98f402d0da9c1af02eac020001ea4d295f3387e9efbf6d791475cb936839eb8d5800ffff046d61696e0000005e07070707008fb5b934050502000000430320053d036d0743035d0100000024747a3252746e76454c564157356455547473424e47366362534132655146695974345270031e0743036a0080897a034f034d031b0200000006030603060306'
);
consolidationResult.source.should.equal('KT1Vwe7wFy6JmspMv4UmFFJU3JLtbfghBTBM');
consolidationResult.dataToSign.should.equal(
Expand Down
6 changes: 5 additions & 1 deletion modules/sdk-coin-xtz/test/unit/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
signedSerializedOriginationTransaction,
parsedTransaction,
} from '../resources';
import { OperationContents } from '@taquito/rpc';
import { XtzLib } from '../../src';

describe('Tezos transaction', function () {
Expand Down Expand Up @@ -104,7 +105,10 @@ describe('Tezos transaction', function () {

it('to sign the transaction if the keys are invalid', async () => {
const tx = new XtzLib.Transaction(coins.get('txtz'));
await tx.initFromParsedTransaction(parsedTransaction);
await tx.initFromParsedTransaction({
...parsedTransaction,
contents: parsedTransaction.contents as OperationContents[],
});
const signer = new XtzLib.KeyPair({ pub: 'sppk7ZWB8diU2TWehxdkWCV2DTFvn1hPz4qLjiD3nJQozKnoSEnSC8b' });
await tx.sign(signer).should.be.rejectedWith('Missing private key');
});
Expand Down
10 changes: 5 additions & 5 deletions modules/sdk-coin-xtz/test/unit/transactionBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ describe('Tezos Transaction builder', function () {
txBuilder.sign({ key: defaultKeyPair.getKeys().prv });
const tx = await txBuilder.build();

tx.id.should.equal('oo9rzcHZcGBBKtUfe3aL82isMf8SscBsLE7PBmBQXA2EKGT9yz7');
tx.id.should.equal('onpN4Zq664YTriyVmBbgEZAReHbucvD31XwvnpP5T9qzfhbanbx');
tx.type.should.equal(TransactionType.WalletInitialization);
tx.source.should.equal('tz2PtJ9zgEgFVTRqy6GXsst54tH3ksEnYvvS');
should.equal(tx.inputs.length, 2);
Expand All @@ -195,12 +195,12 @@ describe('Tezos Transaction builder', function () {
tx.inputs[0].value.should.equal('1420');
tx.inputs[1].address.should.equal('tz2PtJ9zgEgFVTRqy6GXsst54tH3ksEnYvvS');
tx.inputs[1].value.should.equal('1004764');
tx.outputs[0].address.should.equal('KT1JQQUXLfoxL6ifTz2SyQK7ZEAvF1m7KXgC');
tx.outputs[0].address.should.equal('KT1Hdttpv7CBaJ8igdkhCudMHBWUqNviJCTf');
tx.outputs[0].value.should.equal('1000000');
tx.delegate.should.equal('tz1KpbK5v1NB2vg3JHBxXJZhyQ7ur83Xp7iC');
tx.signature.length.should.equal(1);
tx.signature[0].should.equal(
'sigUyznaJo4JdLuyS7wpP5fDe12cUutDiABEYHHMEpaNYY6TQstAfvLJPQTcFWJJ2QRMZxC46nUvKEdaBJfPN5dzCGMQDtXn'
'sigtJtqVf7FJVqkDPyPW878FfCnpCPNb6JJdXAxezepe4t97BwfouYJ6GMqHGSNhevu4uiLSQ2h374a4NxMnA9E9qLXa4j93'
);
const indexesByTransactionType = tx.getIndexesByTransactionType();
Object.keys(indexesByTransactionType).length.should.equal(2);
Expand All @@ -224,7 +224,7 @@ describe('Tezos Transaction builder', function () {
txBuilder.sign({ key: defaultKeyPair.getKeys().prv });
const tx = await txBuilder.build();

tx.id.should.equal('oomXs6PuWtmGwMKoXTNsu9XJHnGXtuRujcHMeYS9y37Xj6sXPHb');
tx.id.should.equal('oos4n1zJAGeqLQrNsnGAfzzj6FeZqbSrnAMVTdC485cinFWN6su');
tx.type.should.equal(TransactionType.AccountUpdate);
tx.source.should.equal('tz2PtJ9zgEgFVTRqy6GXsst54tH3ksEnYvvS');
should.equal(tx.inputs.length, 1);
Expand All @@ -234,7 +234,7 @@ describe('Tezos Transaction builder', function () {
should.not.exist(tx.delegate);
tx.signature.length.should.equal(1);
tx.signature[0].should.equal(
'sigQyYsfhtrJBKZuJSEizDdxoejNVvJWRZPDMWdpXVvdTVix37HzURwXfXsi9METnRzskvjgsBSgiF4pr7RVxzWLuixxJL8U'
'sigTtfcxtvU5zWbsWDJwKvHdDcWYDhgsb9ozmQ44AUGHnSJJgvPR2CvNCUX8axezJKoZRzgv9gSE3GSDh5SEbm31JqM53yyg'
);
const indexesByTransactionType = tx.getIndexesByTransactionType();
indexesByTransactionType.reveal.length.should.equal(1);
Expand Down