Skip to content

Commit e617e31

Browse files
Faizan Dastgirzone117x
authored andcommitted
chore: add signer for signed txs
1 parent 8da9c6d commit e617e31

File tree

2 files changed

+105
-42
lines changed

2 files changed

+105
-42
lines changed

src/api/routes/rosetta/construction.ts

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,40 @@
1-
import * as express from 'express';
21
import { addAsync, RouterWithAsync } from '@awaitjs/express';
3-
import { DataStore, DbBlock } from '../../../datastore/common';
42
import {
5-
RosettaPublicKey,
6-
RosettaConstructionDeriveResponse,
73
NetworkIdentifier,
8-
RosettaOperation,
9-
RosettaMaxFeeAmount,
10-
RosettaConstructionPreprocessResponse,
11-
RosettaOptions,
12-
RosettaConstructionMetadataResponse,
4+
RosettaConstructionDeriveResponse,
135
RosettaConstructionHashRequest,
146
RosettaConstructionHashResponse,
7+
RosettaConstructionMetadataResponse,
8+
RosettaConstructionPreprocessResponse,
9+
RosettaMaxFeeAmount,
10+
RosettaOperation,
11+
RosettaOptions,
12+
RosettaPublicKey,
1513
} from '@blockstack/stacks-blockchain-api-types';
16-
import { deserializeTransaction } from '@blockstack/stacks-transactions/lib/transaction';
17-
import { BufferReader } from '@blockstack/stacks-transactions/lib/bufferReader';
18-
import { AddressHashMode } from '@blockstack/stacks-transactions';
1914
import {
20-
isSingleSig,
2115
emptyMessageSignature,
16+
isSingleSig,
2217
} from '@blockstack/stacks-transactions/lib/authorization';
23-
24-
import { rosettaValidateRequest, ValidSchema, makeRosettaError } from './../../rosetta-validate';
18+
import { BufferReader } from '@blockstack/stacks-transactions/lib/bufferReader';
19+
import { deserializeTransaction } from '@blockstack/stacks-transactions/lib/transaction';
20+
import * as express from 'express';
21+
import { StacksCoreRpcClient } from '../../../core-rpc/client';
22+
import { DataStore, DbBlock } from '../../../datastore/common';
23+
import { FoundOrNot, hexToBuffer, isValidC32Address } from '../../../helpers';
24+
import { RosettaConstants, RosettaErrors } from '../../rosetta-constants';
2525
import {
26-
publicKeyToBitcoinAddress,
2726
bitcoinAddressToSTXAddress,
27+
getOperations,
2828
getOptionsFromOperations,
29-
isSymbolSupported,
29+
getSingers,
3030
isDecimalsSupported,
31+
isSignedTransaction,
32+
isSymbolSupported,
33+
publicKeyToBitcoinAddress,
3134
rawTxToBaseTx,
32-
getOperations,
3335
rawTxToStacksTransaction,
34-
isSignedTransaction,
3536
} from './../../../rosetta-helpers';
36-
import { isValidC32Address, FoundOrNot, hexToBuffer } from '../../../helpers';
37-
import { StacksCoreRpcClient } from '../../../core-rpc/client';
38-
import { RosettaErrors, RosettaConstants } from '../../rosetta-constants';
37+
import { makeRosettaError, rosettaValidateRequest, ValidSchema } from './../../rosetta-validate';
3938

4039
export function createRosettaConstructionRouter(db: DataStore): RouterWithAsync {
4140
const router = addAsync(express.Router());
@@ -249,7 +248,6 @@ export function createRosettaConstructionRouter(db: DataStore): RouterWithAsync
249248
res.status(400).json(makeRosettaError(valid));
250249
return;
251250
}
252-
253251
const inputTx = req.body.transaction;
254252
const singed = req.body.signed;
255253
const transaction = rawTxToStacksTransaction(inputTx);
@@ -259,9 +257,16 @@ export function createRosettaConstructionRouter(db: DataStore): RouterWithAsync
259257
return;
260258
}
261259
const operations = getOperations(rawTxToBaseTx(inputTx));
262-
res.json({
263-
operations: operations,
264-
});
260+
if (singed) {
261+
res.json({
262+
operations: operations,
263+
account_identifier_signers: getSingers(transaction),
264+
});
265+
} else {
266+
res.json({
267+
operations: operations,
268+
});
269+
}
265270
});
266271

267272
return router;

src/rosetta-helpers.ts

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,37 @@
1-
import { BaseTx, DbTxStatus, DbTxTypeId } from './datastore/common';
2-
import { getTxTypeString, getTxStatusString } from './api/controllers/db-controller';
31
import {
4-
assertNotNullish as unwrapOptional,
5-
bufferToHexPrefixString,
6-
hexToBuffer,
7-
} from './helpers';
8-
import { RosettaOperation, RosettaOptions } from '@blockstack/stacks-blockchain-api-types';
2+
RosettaAccountIdentifier,
3+
RosettaOperation,
4+
RosettaOptions,
5+
} from '@blockstack/stacks-blockchain-api-types';
6+
import {
7+
addressToString,
8+
AuthType,
9+
ContractCallPayload,
10+
PayloadType,
11+
TokenTransferPayload,
12+
} from '@blockstack/stacks-transactions';
13+
import {
14+
emptyMessageSignature,
15+
isSingleSig,
16+
} from '@blockstack/stacks-transactions/lib/authorization';
17+
import { BufferReader } from '@blockstack/stacks-transactions/lib/bufferReader';
918
import {
10-
StacksTransaction,
1119
deserializeTransaction,
20+
StacksTransaction,
1221
} from '@blockstack/stacks-transactions/lib/transaction';
13-
import { BufferReader } from '@blockstack/stacks-transactions/lib/bufferReader';
22+
import { txidFromData } from '@blockstack/stacks-transactions/lib/utils';
1423
import * as btc from 'bitcoinjs-lib';
1524
import * as c32check from 'c32check';
16-
import { RosettaNetworks, RosettaConstants } from './api/rosetta-constants';
17-
import { readTransaction, TransactionPayloadTypeID } from './p2p/tx';
18-
import { txidFromData } from '@blockstack/stacks-transactions/lib/utils';
25+
import { getTxStatusString, getTxTypeString } from './api/controllers/db-controller';
26+
import { RosettaConstants, RosettaNetworks } from './api/rosetta-constants';
27+
import { BaseTx, DbTxStatus, DbTxTypeId } from './datastore/common';
1928
import { getTxSenderAddress, getTxSponsorAddress } from './event-stream/reader';
2029
import {
21-
isSingleSig,
22-
emptyMessageSignature,
23-
} from '@blockstack/stacks-transactions/lib/authorization';
24-
import { addressToString } from '@blockstack/stacks-transactions/lib/types';
30+
assertNotNullish as unwrapOptional,
31+
bufferToHexPrefixString,
32+
hexToBuffer,
33+
} from './helpers';
34+
import { readTransaction, TransactionPayloadTypeID } from './p2p/tx';
2535

2636
enum CoinAction {
2737
CoinSpent = 'coin_spent',
@@ -348,3 +358,51 @@ export function rawTxToBaseTx(raw_tx: string): BaseTx {
348358

349359
return dbtx;
350360
}
361+
362+
export function getSingers(transaction: StacksTransaction): RosettaAccountIdentifier[] | undefined {
363+
let address;
364+
if (transaction.payload.payloadType == PayloadType.TokenTransfer) {
365+
address = transaction.payload.recipient.address;
366+
} else if (transaction.payload.payloadType == PayloadType.ContractCall) {
367+
address = transaction.payload.contractAddress;
368+
} else {
369+
return;
370+
}
371+
const { type, version } = address;
372+
373+
const account_identifier_signers: RosettaAccountIdentifier[] = [];
374+
if (transaction.auth.authType == AuthType.Standard) {
375+
if (transaction.auth.spendingCondition) {
376+
const singer = {
377+
address: addressToString({
378+
version: version,
379+
hash160: transaction.auth.spendingCondition.signer,
380+
type: type,
381+
}),
382+
};
383+
account_identifier_signers.push(singer);
384+
}
385+
} else if (transaction.auth.authType == AuthType.Sponsored) {
386+
if (transaction.auth.spendingCondition) {
387+
const singer = {
388+
address: addressToString({
389+
version: version,
390+
hash160: transaction.auth.spendingCondition.signer,
391+
type: type,
392+
}),
393+
};
394+
account_identifier_signers.push(singer);
395+
}
396+
if (transaction.auth.sponsorSpendingCondition) {
397+
const sponsored = {
398+
address: addressToString({
399+
version: version,
400+
hash160: transaction.auth.sponsorSpendingCondition.signer,
401+
type: type,
402+
}),
403+
};
404+
account_identifier_signers.push(sponsored);
405+
}
406+
}
407+
return account_identifier_signers;
408+
}

0 commit comments

Comments
 (0)