Skip to content

Commit

Permalink
feat: replace attestor handler with attestor functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Polybius93 committed Jul 17, 2024
1 parent 6a2bbda commit 8c3174a
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 77 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,15 @@
"@noble/hashes": "^1.4.0",
"@scure/base": "^1.1.6",
"@scure/btc-signer": "^1.3.1",
"@types/ramda": "^0.30.1",
"bip32": "^4.0.0",
"bitcoinjs-lib": "^6.1.5",
"chalk": "^5.3.0",
"decimal.js": "^10.4.3",
"ethers": "5.7.2",
"ledger-bitcoin": "^0.2.3",
"prompts": "^2.4.2",
"ramda": "^0.30.1",
"scure": "^1.6.0",
"tiny-secp256k1": "^2.2.3"
}
Expand Down
75 changes: 0 additions & 75 deletions src/attestor-handlers/attestor-handler.ts

This file was deleted.

83 changes: 83 additions & 0 deletions src/functions/attestor/attestor-request.functions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { isEmpty, join } from 'ramda';
import {
FundingTXAttestorInfo,
WithdrawDepositTXAttestorInfo,
} from 'src/models/attestor.models.js';
import { AttestorError } from 'src/models/errors.js';

export async function sendRequest(url: string, body: string): Promise<boolean | string> {
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' },
body,
});
if (!response.ok) {
throw new AttestorError(`Attestor Response ${url} was not OK: ${response.statusText}`);
}
return true;
}

export async function submitFundingPSBT(
attestorRootURLs: string[],
fundingTXAttestorInfo: FundingTXAttestorInfo
): Promise<void> {
if (isEmpty(attestorRootURLs)) {
throw new AttestorError('No Attestor URLs provided');
}

const fundingEndpoints = attestorRootURLs.map(url => `${url}/app/create-psbt-event`);

const body = JSON.stringify({
uuid: fundingTXAttestorInfo.vaultUUID,
funding_transaction_psbt: fundingTXAttestorInfo.fundingPSBT,
mint_address: fundingTXAttestorInfo.userEthereumAddress,
chain: fundingTXAttestorInfo.attestorChainID,
alice_pubkey: fundingTXAttestorInfo.userBitcoinTaprootPublicKey,
});

const attestorResponses: (boolean | string)[] = await Promise.all(
fundingEndpoints.map(async url =>
sendRequest(url, body)
.then(response => response)
.catch(error => error.message)
)
);

if (attestorResponses.every(response => response !== true)) {
throw new AttestorError(
`Error sending [Funding] Transaction to Attestors:
${join('|', attestorResponses)}`
);
}
}

export async function submitWithdrawDepositPSBT(
attestorRootURLs: string[],
withdrawDepositTXAttestorInfo: WithdrawDepositTXAttestorInfo
): Promise<void> {
if (isEmpty(attestorRootURLs)) {
throw new AttestorError('No Attestor URLs provided');
}

const depositWithdrawEndpoints = attestorRootURLs.map(url => `${url}/app/withdraw`);

const body = JSON.stringify({
uuid: withdrawDepositTXAttestorInfo.vaultUUID,
wd_psbt: withdrawDepositTXAttestorInfo.depositWithdrawPSBT,
});

const attestorResponses: (boolean | string)[] = await Promise.all(
depositWithdrawEndpoints.map(async url =>
sendRequest(url, body)
.then(response => response)
.catch(error => error.message)
)
);

if (attestorResponses.every(response => response !== true)) {
throw new AttestorError(
`Error sending [Deposit/Withdraw] Transaction to Attestors:
${join('|', attestorResponses)}`
);
}
}
4 changes: 4 additions & 0 deletions src/functions/attestor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export {
submitFundingPSBT,
submitWithdrawDepositPSBT,
} from '../attestor/attestor-request.functions.js';
2 changes: 0 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { AttestorHandler } from './attestor-handlers/attestor-handler.js';
import { LedgerDLCHandler } from './dlc-handlers/ledger-dlc-handler.js';
import { PrivateKeyDLCHandler } from './dlc-handlers/private-key-dlc-handler.js';
import { SoftwareWalletDLCHandler } from './dlc-handlers/software-wallet-dlc-handler.js';
Expand All @@ -12,6 +11,5 @@ export {
SoftwareWalletDLCHandler,
EthereumHandler,
ReadOnlyEthereumHandler,
AttestorHandler,
ProofOfReserveHandler,
};
51 changes: 51 additions & 0 deletions tests/unit/attestor-request-functions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import * as attestorRequestFunctions from '../../src/functions/attestor/attestor-request.functions.js';
import { submitFundingPSBT } from '../../src/functions/attestor/attestor-request.functions.js';

describe('Attestor ', () => {
beforeEach(() => {
jest.clearAllMocks();
});
describe('submitFundingPSBT', () => {
it('should not throw an error if all requests were succesful', async () => {
jest
.spyOn(attestorRequestFunctions, 'sendRequest')
.mockImplementationOnce(async () => true)
.mockImplementationOnce(async () => true)
.mockImplementationOnce(async () => true);

await expect(
submitFundingPSBT(
['http://localhost:3000', 'http://localhost:4000', 'http://localhost:5000'],
{
vaultUUID: 'vaultUUID',
fundingPSBT: 'fundingPSBT',
userEthereumAddress: 'userEthereumAddress',
attestorChainID: 'evm-arbitrum',
userBitcoinTaprootPublicKey: 'userBitcoinTaprootPublicKey',
}
)
).resolves.not.toThrow();
});

it('should not throw an error if not all requests were succesful', async () => {
jest
.spyOn(attestorRequestFunctions, 'sendRequest')
.mockImplementationOnce(async () => true)
.mockImplementationOnce(async () => true)
.mockImplementationOnce(async () => false);

await expect(
submitFundingPSBT(
['http://localhost:3000', 'http://localhost:4000', 'http://localhost:5000'],
{
vaultUUID: 'vaultUUID',
fundingPSBT: 'fundingPSBT',
userEthereumAddress: 'userEthereumAddress',
attestorChainID: 'evm-arbitrum',
userBitcoinTaprootPublicKey: 'userBitcoinTaprootPublicKey',
}
)
).resolves.not.toThrow();
});
});
});
24 changes: 24 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,13 @@
"@types/node" "*"
kleur "^3.0.3"

"@types/ramda@^0.30.1":
version "0.30.1"
resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.30.1.tgz#316257fec12747bb39a2e921df48a9dcb8c164a9"
integrity sha512-aoyF/ADPL6N+/NXXfhPWF+Qj6w1Cql59m9wX0Gi15uyF+bpzXeLd63HPdiTDE2bmLXfNcVufsDPKmbfOrOzTBA==
dependencies:
types-ramda "^0.30.1"

"@types/stack-utils@^2.0.0":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8"
Expand Down Expand Up @@ -4207,6 +4214,11 @@ queue-microtask@^1.2.2:
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==

ramda@^0.30.1:
version "0.30.1"
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.30.1.tgz#7108ac95673062b060025052cd5143ae8fc605bf"
integrity sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==

randombytes@^2.0.1, randombytes@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
Expand Down Expand Up @@ -4747,6 +4759,11 @@ ts-node@^10.9.2:
v8-compile-cache-lib "^3.0.1"
yn "3.1.1"

ts-toolbelt@^9.6.0:
version "9.6.0"
resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz#50a25426cfed500d4a09bd1b3afb6f28879edfd5"
integrity sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==

tslib@^1.9.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
Expand Down Expand Up @@ -4808,6 +4825,13 @@ typeforce@^1.11.3, typeforce@^1.11.5, typeforce@^1.18.0:
resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc"
integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==

types-ramda@^0.30.1:
version "0.30.1"
resolved "https://registry.yarnpkg.com/types-ramda/-/types-ramda-0.30.1.tgz#03d255128e3696aeaac76281ca19949e01dddc78"
integrity sha512-1HTsf5/QVRmLzcGfldPFvkVsAdi1db1BBKzi7iW3KBUlOICg/nKnFS+jGqDJS3YD8VsWbAh7JiHeBvbsw8RPxA==
dependencies:
ts-toolbelt "^9.6.0"

typescript-eslint@^7.7.0:
version "7.11.0"
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-7.11.0.tgz#7a208fc1d178b3fed58e33ce37150ac6efecf1fb"
Expand Down

0 comments on commit 8c3174a

Please sign in to comment.