Skip to content

Commit

Permalink
better memo derivation, cleaning
Browse files Browse the repository at this point in the history
  • Loading branch information
gianfra-t committed Nov 12, 2024
1 parent 9e92784 commit a6be1ed
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 42 deletions.
17 changes: 9 additions & 8 deletions signer-service/src/api/services/sep10.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ const { Keypair } = require('stellar-sdk');
const { TransactionBuilder, Networks } = require('stellar-sdk');
const { fetchTomlValues } = require('../helpers/anchors');
const { verifySiweMessage } = require('./siwe.service');
const { keccak256 } = require('viem/utils');

const { TOKEN_CONFIG } = require('../../constants/tokenConfig');
const { SEP10_MASTER_SECRET, CLIENT_SECRET } = require('../../constants/constants');
const { SEP10_MASTER_SECRET, CLIENT_DOMAIN_SECRET } = require('../../constants/constants');

const NETWORK_PASSPHRASE = Networks.PUBLIC;

async function deriveMemoFromAddress(address) {
const hash = keccak256(address);
return BigInt(hash).toString().slice(0, 15);
}

// we validate a challenge for a given nonce. From it we obtain the address and derive the memo
// we can then ensure that the memo is the same as the one we expect from the anchor challenge
const getAndValidateMemo = async (nonce, userChallengeSignature) => {
Expand All @@ -22,17 +28,13 @@ const getAndValidateMemo = async (nonce, userChallengeSignature) => {
throw new Error(`Could not verify signature: ${e.message}`);
}

const memo = deriveMemoFromAddress(message.address);
const memo = await deriveMemoFromAddress(message.address);
return memo;
};

const deriveMemoFromAddress = (address) => {
return address.slice(5, 15).replace(/\D/g, '');
};

exports.signSep10Challenge = async (challengeXDR, outToken, clientPublicKey, userChallengeSignature, nonce) => {
const masterStellarKeypair = Keypair.fromSecret(SEP10_MASTER_SECRET);
const clientDomainStellarKeypair = Keypair.fromSecret(CLIENT_SECRET);
const clientDomainStellarKeypair = Keypair.fromSecret(CLIENT_DOMAIN_SECRET);

// we validate a challenge for a given nonce. From it we obtain the address and derive the memo
// we can then ensure that the memo is the same as the one we expect from the anchor challenge
Expand All @@ -41,7 +43,6 @@ exports.signSep10Challenge = async (challengeXDR, outToken, clientPublicKey, use
try {
memo = await getAndValidateMemo(nonce, userChallengeSignature);
} catch (e) {
console.log(e);
throw new Error(`Could not verify signature or derive memo: ${e.message}`);
}

Expand Down
19 changes: 8 additions & 11 deletions src/services/anchor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { EventStatus } from '../../components/GenericEvent';
import { OutputTokenDetails, OutputTokenType } from '../../constants/tokenConfig';
import { fetchSep10Signatures, fetchSigningServiceAccountId, SignerServiceSep10Request } from '../signingService';
import { SiweSignatureData } from '../../hooks/useSignChallenge';
import { keccak256 } from 'viem/utils';

import { config } from '../../config';
import { OUTPUT_TOKEN_CONFIG } from '../../constants/tokenConfig';
Expand Down Expand Up @@ -63,6 +64,12 @@ export const fetchTomlValues = async (TOML_FILE_URL: string): Promise<TomlValues
};
};

//A memo derivation. TODO: Secure? how to check for collisions?
async function deriveMemoFromAddress(address: `0x${string}`) {
const hash = keccak256(address);
return BigInt(hash).toString().slice(0, 15);
}

// Return the URLSearchParams and the account (master/omnibus or ephemeral) that was used for SEP-10
async function getUrlParams(
ephemeralAccount: string,
Expand All @@ -86,7 +93,7 @@ async function getUrlParams(
urlParams: new URLSearchParams({
account: sep10Account,
client_domain: config.applicationClientDomain,
memo: deriveMemoFromAddress(address),
memo: await deriveMemoFromAddress(address),
}),
sep10Account,
};
Expand All @@ -102,26 +109,17 @@ const sep10SignaturesWithLoginRefresh = async (
args: SignerServiceSep10Request,
) => {
try {
console.log(args);
return await fetchSep10Signatures(args);
} catch (error: any) {
console.log(error.message);
if (error.message === 'Invalid signature') {
let { nonce, signature } = await refreshFunction();
console.log('new signature', signature);
console.log('ne nonce ', nonce);
let regreshedArgs = { ...args, maybeChallengeSignature: signature, maybeNonce: nonce };
return await fetchSep10Signatures(regreshedArgs);
}
throw new Error('Could not fetch sep 10 signatures from backend');
}
};

//TODO A very naive memo derivation for testing. NOT SECURE
const deriveMemoFromAddress = (address: `0x${string}`) => {
return address.slice(5, 15).replace(/\D/g, '');
};

export const sep10 = async (
tomlValues: TomlValues,
stellarEphemeralSecret: string,
Expand Down Expand Up @@ -194,7 +192,6 @@ export const sep10 = async (
if (!usesMemo) {
transactionSigned.sign(ephemeralKeys);
} else {
console.log(sep10Account);
transactionSigned.addSignature(sep10Account, masterClientSignature);
}

Expand Down
62 changes: 39 additions & 23 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ __metadata:
version: 8
cacheKey: 10

"@adraffy/ens-normalize@npm:^1.10.1":
version: 1.11.0
resolution: "@adraffy/ens-normalize@npm:1.11.0"
checksum: 10/abef75f21470ea43dd6071168e092d2d13e38067e349e76186c78838ae174a46c3e18ca50921d05bea6ec3203074147c9e271f8cb6531d1c2c0e146f3199ddcb
languageName: node
linkType: hard

"@adraffy/ens-normalize@npm:1.10.1, @adraffy/ens-normalize@npm:^1.8.8":
version: 1.10.1
resolution: "@adraffy/ens-normalize@npm:1.10.1"
checksum: 10/4cb938c4abb88a346d50cb0ea44243ab3574330c81d4f5aaaf9dfee584b96189d0faa404de0fcbef5a1b73909ea4ebc3e63d84bd23f9949e5c8d4085207a5091
languageName: node
linkType: hard

"@adraffy/ens-normalize@npm:^1.10.1":
version: 1.11.0
resolution: "@adraffy/ens-normalize@npm:1.11.0"
checksum: 10/abef75f21470ea43dd6071168e092d2d13e38067e349e76186c78838ae174a46c3e18ca50921d05bea6ec3203074147c9e271f8cb6531d1c2c0e146f3199ddcb
languageName: node
linkType: hard

"@alloc/quick-lru@npm:^5.2.0":
version: 5.2.0
resolution: "@alloc/quick-lru@npm:5.2.0"
Expand Down Expand Up @@ -2621,6 +2621,15 @@ __metadata:
languageName: node
linkType: hard

"@noble/curves@npm:1.2.0":
version: 1.2.0
resolution: "@noble/curves@npm:1.2.0"
dependencies:
"@noble/hashes": "npm:1.3.2"
checksum: 10/94e02e9571a9fd42a3263362451849d2f54405cb3ce9fa7c45bc6b9b36dcd7d1d20e2e1e14cfded24937a13d82f1e60eefc4d7a14982ce0bc219a9fc0f51d1f9
languageName: node
linkType: hard

"@noble/curves@npm:1.4.0, @noble/curves@npm:^1.3.0, @noble/curves@npm:~1.4.0":
version: 1.4.0
resolution: "@noble/curves@npm:1.4.0"
Expand All @@ -2646,14 +2655,21 @@ __metadata:
languageName: node
linkType: hard

"@noble/hashes@npm:1.3.2":
version: 1.3.2
resolution: "@noble/hashes@npm:1.3.2"
checksum: 10/685f59d2d44d88e738114b71011d343a9f7dce9dfb0a121f1489132f9247baa60bc985e5ec6f3213d114fbd1e1168e7294644e46cbd0ce2eba37994f28eeb51b
languageName: node
linkType: hard

"@noble/hashes@npm:1.4.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.3.3, @noble/hashes@npm:~1.4.0":
version: 1.4.0
resolution: "@noble/hashes@npm:1.4.0"
checksum: 10/e156e65794c473794c52fa9d06baf1eb20903d0d96719530f523cc4450f6c721a957c544796e6efd0197b2296e7cd70efeb312f861465e17940a3e3c7e0febc6
languageName: node
linkType: hard

"@noble/hashes@npm:1.5.0, @noble/hashes@npm:^1.4.0, @noble/hashes@npm:^1.5.0, @noble/hashes@npm:~1.5.0":
"@noble/hashes@npm:1.5.0, @noble/hashes@npm:^1.1.2, @noble/hashes@npm:^1.4.0, @noble/hashes@npm:^1.5.0, @noble/hashes@npm:~1.5.0":
version: 1.5.0
resolution: "@noble/hashes@npm:1.5.0"
checksum: 10/da7fc7af52af7afcf59810a7eea6155075464ff462ffda2572dc6d57d53e2669b1ea2ec774e814f6273f1697e567f28d36823776c9bf7068cba2a2855140f26e
Expand Down Expand Up @@ -17401,6 +17417,21 @@ __metadata:
languageName: node
linkType: hard

"ws@npm:8.17.1, ws@npm:~8.17.1":
version: 8.17.1
resolution: "ws@npm:8.17.1"
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: ">=5.0.2"
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
checksum: 10/4264ae92c0b3e59c7e309001e93079b26937aab181835fb7af79f906b22cd33b6196d96556dafb4e985742dd401e99139572242e9847661fdbc96556b9e6902d
languageName: node
linkType: hard

"ws@npm:8.18.0, ws@npm:^8.16.0":
version: 8.18.0
resolution: "ws@npm:8.18.0"
Expand Down Expand Up @@ -17446,21 +17477,6 @@ __metadata:
languageName: node
linkType: hard

"ws@npm:~8.17.1":
version: 8.17.1
resolution: "ws@npm:8.17.1"
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: ">=5.0.2"
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
checksum: 10/4264ae92c0b3e59c7e309001e93079b26937aab181835fb7af79f906b22cd33b6196d96556dafb4e985742dd401e99139572242e9847661fdbc96556b9e6902d
languageName: node
linkType: hard

"xmlhttprequest-ssl@npm:~2.0.0":
version: 2.0.0
resolution: "xmlhttprequest-ssl@npm:2.0.0"
Expand Down

0 comments on commit a6be1ed

Please sign in to comment.