Skip to content

Commit

Permalink
Add support of CAP40 ed25519SignedPayload signer for SetOptionOp (#542)
Browse files Browse the repository at this point in the history
* Add TypeScript interfaces for Ed25519SignedPayload signers
  • Loading branch information
orbitlens authored Sep 7, 2022
1 parent 832824d commit 808fca3
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 3 deletions.
8 changes: 8 additions & 0 deletions src/operation.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,14 @@ export class Operation {
.signer()
.key()
.hashX();
} else if (arm === 'ed25519SignedPayload') {
const signedPayload = attrs
.signer()
.key()
.ed25519SignedPayload();
signer.ed25519SignedPayload = StrKey.encodeSignedPayload(
signedPayload.toXDR()
);
}

signer.weight = attrs.signer().weight();
Expand Down
17 changes: 17 additions & 0 deletions src/operations/set_options.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ function weightCheckFunction(value, name) {
* @param {string} [opts.signer.ed25519PublicKey] - The ed25519 public key of the signer.
* @param {Buffer|string} [opts.signer.sha256Hash] - sha256 hash (Buffer or hex string) of preimage that will unlock funds. Preimage should be used as signature of future transaction.
* @param {Buffer|string} [opts.signer.preAuthTx] - Hash (Buffer or hex string) of transaction that will unlock funds.
* @param {string} [opts.signer.ed25519SignedPayload] - Signed payload signer (ed25519 public key + raw payload) for atomic transaction signature disclosure.
* @param {number|string} [opts.signer.weight] - The weight of the new signer (0 to delete or 1-255)
* @param {string} [opts.homeDomain] - sets the home domain used for reverse federation lookup.
* @param {string} [opts.source] - The source account (defaults to transaction source).
Expand Down Expand Up @@ -152,6 +153,22 @@ export function setOptions(opts) {
setValues += 1;
}

if (opts.signer.ed25519SignedPayload) {
if (!StrKey.isValidSignedPayload(opts.signer.ed25519SignedPayload)) {
throw new Error('signer.ed25519SignedPayload is invalid.');
}
const rawKey = StrKey.decodeSignedPayload(
opts.signer.ed25519SignedPayload
);
const signedPayloadXdr = xdr.SignerKeyEd25519SignedPayload.fromXDR(
rawKey
);

// eslint-disable-next-line new-cap
key = xdr.SignerKey.signerKeyTypeEd25519SignedPayload(signedPayloadXdr);
setValues += 1;
}

if (setValues !== 1) {
throw new Error(
'Signer object must contain exactly one of signer.ed25519PublicKey, signer.sha256Hash, signer.preAuthTx.'
Expand Down
32 changes: 32 additions & 0 deletions test/unit/operation_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,38 @@ describe('Operation', function() {
expect(obj.signer.weight).to.be.equal(opts.signer.weight);
});

it('creates a setOptionsOp with signed payload signer', function() {
var opts = {};

var pubkey = 'GCEZWKCA5VLDNRLN3RPRJMRZOX3Z6G5CHCGSNFHEYVXM3XOJMDS674JZ';
var signedPayload = new StellarBase.xdr.SignerKeyEd25519SignedPayload({
ed25519: StellarBase.StrKey.decodeEd25519PublicKey(pubkey),
payload: Buffer.from('test')
});
var xdrSignerKey = StellarBase.xdr.SignerKey.signerKeyTypeEd25519SignedPayload(
signedPayload
);
var payloadKey = StellarBase.SignerKey.encodeSignerKey(xdrSignerKey);

//var rawSignedPayload = Buffer.concat([StellarBase.StrKey.decodeEd25519PublicKey(pubkey), Buffer.from('test')]);
//var payloadKey = StellarBase.StrKey.encodeSignedPayload(rawSignedPayload);

opts.signer = {
ed25519SignedPayload: payloadKey,
weight: 10
};

let op = StellarBase.Operation.setOptions(opts);
var xdr = op.toXDR('hex');
var operation = StellarBase.xdr.Operation.fromXDR(
Buffer.from(xdr, 'hex')
);
var obj = StellarBase.Operation.fromXDRObject(operation);

expect(obj.signer.ed25519SignedPayload).to.be.equal(payloadKey);
expect(obj.signer.weight).to.be.equal(opts.signer.weight);
});

it('empty homeDomain is decoded correctly', function() {
const keypair = StellarBase.Keypair.random();
const account = new StellarBase.Account(keypair.publicKey(), '0');
Expand Down
22 changes: 19 additions & 3 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ export namespace Signer {
preAuthTx: Buffer;
weight: number | undefined;
}
interface Ed25519SignedPayload {
ed25519SignedPayload: string;
weight?: number | string;
}
}
export namespace SignerKeyOptions {
interface Ed25519PublicKey {
Expand All @@ -272,16 +276,21 @@ export namespace SignerKeyOptions {
interface PreAuthTx {
preAuthTx: Buffer | string;
}
interface Ed25519SignedPayload {
ed25519SignedPayload: string;
}
}
export type Signer =
| Signer.Ed25519PublicKey
| Signer.Sha256Hash
| Signer.PreAuthTx;
| Signer.PreAuthTx
| Signer.Ed25519SignedPayload;

export type SignerKeyOptions =
| SignerKeyOptions.Ed25519PublicKey
| SignerKeyOptions.Sha256Hash
| SignerKeyOptions.PreAuthTx;
| SignerKeyOptions.PreAuthTx
| SignerKeyOptions.Ed25519SignedPayload;

export namespace SignerOptions {
interface Ed25519PublicKey {
Expand All @@ -296,11 +305,16 @@ export namespace SignerOptions {
preAuthTx: Buffer | string;
weight?: number | string;
}
interface Ed25519SignedPayload {
ed25519SignedPayload: string;
weight?: number | string;
}
}
export type SignerOptions =
| SignerOptions.Ed25519PublicKey
| SignerOptions.Sha256Hash
| SignerOptions.PreAuthTx;
| SignerOptions.PreAuthTx
| SignerOptions.Ed25519SignedPayload;

export namespace OperationType {
type CreateAccount = 'createAccount';
Expand Down Expand Up @@ -666,6 +680,8 @@ export namespace Operation {
? Signer.Sha256Hash
: T extends { preAuthTx: any }
? Signer.PreAuthTx
: T extends { ed25519SignedPayload: any }
? Signer.Ed25519SignedPayload
: never;
}
function setOptions<T extends SignerOptions = never>(
Expand Down

0 comments on commit 808fca3

Please sign in to comment.