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
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @Luisfc68 @MaximStanciu8 @gsoares85 @Dominikkq @AndresQuijano
7 changes: 5 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ on:
branches: [ main ]
pull_request:

permissions:
contents: read
permissions: read-all

jobs:
validation:
Expand All @@ -19,6 +18,10 @@ jobs:
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
with:
node-version: '19.6.0'
- name: NPM Login
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm config set //npm.pkg.github.com/:_authToken $GITHUB_TOKEN
- name: Install dependencies
run: npm ci && npm run build
- name: Validate code format
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ However we advice to only use `Mainnet` or `Testnet` for integration purposes as
- **disableChecksum**: this parameter tells the FlyoverSDK whether to disable the RSK checksum validation for the RSK addresses involved in the PegIn and PegOut operations or not. It is false by default.

## Connect to RSK
If you need to connect to RSK to execute some operation then you need to create an RSKConnection and provide it to
Flyover object
If you need to connect to RSK to execute some operation then you need to create a Connection object and provide it to the Flyover object
```javascript
const rsk = await BlockchainConnection.createUsingStandard(window.ethereum)
const flyover = new Flyover({ rskConnection: rsk, network: 'Regtest' })
Expand All @@ -77,7 +76,7 @@ Also you can provide your own regtest LBC address if you want to connect to a lo
customLbcAddress: '0x1eD614cd3443EFd9c70F04b6d777aed947A4b0c4'
})
```
There are 3 ways to create an RSK connection, you can check them in RSKConnection class documentation
There are two types of connection; the [BlockchainConnection](https://github.com/rsksmart/bridges-core-sdk/blob/main/docs/classes/BlockchainConnection.md) and the [BlockchainReadOnlyConnection](https://github.com/rsksmart/bridges-core-sdk/blob/main/docs/classes/BlockchainReadOnlyConnection.md). The difference between them is that with the `BlockchainReadOnlyConnection` you wont be able to sign and broadcast transactions. For the alternatives to create the connection objects you can refer to the documentation of each one of the classes.

### Flyover utils
FlyoverSDK exports an object with a collection of util functions that the client application might use during the integration with the SDK. You can see the list of the utility functions [here](./docs/modules.md#flyoverutils) and also when importing the `FlyoverUtils` object from the SDK package every function has a JsDoc explaining its usage.
Expand Down
8 changes: 6 additions & 2 deletions integration-test/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface IntegrationTestConfig {
peginAmount: bigint
pegoutAmount: bigint
mempoolSpaceUrl: string
testContractAddress: string
}

function getConfig (): IntegrationTestConfig {
Expand All @@ -23,7 +24,8 @@ function getConfig (): IntegrationTestConfig {
TEST_BTC_ADDRESS: btcAddress,
TEST_PEGIN_AMOUNT: peginAmount,
TEST_PEGOUT_AMOUNT: pegoutAmount,
TEST_MEMPOOL_SPACE_URL: mempoolSpaceUrl
TEST_MEMPOOL_SPACE_URL: mempoolSpaceUrl,
TEST_CONTRACT_ADDRESS: testContractAddress
} = process.env
assertTruthy(mnemonic, 'Missing test configuration: TEST_MNEMONIC')
assertTruthy(providerId, 'Missing test configuration: TEST_PROVIDER_ID')
Expand All @@ -34,6 +36,7 @@ function getConfig (): IntegrationTestConfig {
assertTruthy(pegoutAmount, 'Missing test configuration: TEST_PEGOUT_AMOUNT')
assertTruthy(mempoolSpaceUrl, 'Missing test configuration: TEST_MEMPOOL_SPACE_URL')
assertTruthy(network, 'Missing test configuration: TEST_NETWORK')
assertTruthy(testContractAddress, 'Missing test configuration: TEST_CONTRACT_ADDRESS')
return {
network: network as keyof typeof FlyoverNetworks,
testMnemonic: mnemonic,
Expand All @@ -43,7 +46,8 @@ function getConfig (): IntegrationTestConfig {
nodeUrl,
rskAddress,
btcAddress,
mempoolSpaceUrl
mempoolSpaceUrl,
testContractAddress
}
}

Expand Down
1 change: 1 addition & 0 deletions integration-test/example.env
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ TEST_BTC_ADDRESS=<a rsk address>
TEST_PEGIN_AMOUNT=5000000000000000
TEST_PEGOUT_AMOUNT=5000000000000000
TEST_MEMPOOL_SPACE_URL=<mempool space api url>
TEST_CONTRACT_ADDRESS=<a rsk address>
5 changes: 3 additions & 2 deletions integration-test/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 2 additions & 5 deletions integration-test/test/client.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, test, beforeAll, expect } from '@jest/globals'
import { assertTruthy, BlockchainConnection } from '@rsksmart/bridges-core-sdk'
import { assertTruthy, BlockchainReadOnlyConnection } from '@rsksmart/bridges-core-sdk'
import { Flyover } from '@rsksmart/flyover-sdk'
import { integrationTestConfig } from '../config'
import { fakeTokenResolver } from './common/utils'
Expand All @@ -14,10 +14,7 @@ describe('Flyover SDK client should', () => {
captchaTokenResolver: fakeTokenResolver,
disableChecksum: true
})
const rsk = await BlockchainConnection.createUsingPassphrase(
integrationTestConfig.testMnemonic,
integrationTestConfig.nodeUrl
)
const rsk = await BlockchainReadOnlyConnection.createUsingRpc(integrationTestConfig.nodeUrl)
await flyover.connectToRsk(rsk)
})

Expand Down
41 changes: 41 additions & 0 deletions integration-test/test/common/TestContract.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.2 <0.9.0;

contract TestContract {

event Deposit(address indexed destination, uint256 amount);
event Withdraw(address indexed destination, uint256 amount);
event ValueChanged(uint256 oldValue, uint256 newValue);

mapping(address => uint256) private balances;
uint256 private value;

function save(address destination) public payable {
uint256 amount = msg.value;
balances[destination] += amount;
emit Deposit(destination, amount);
}

function setValue(uint256 _value) external {
emit ValueChanged(value, _value);
value = _value;
}

function retrieveValue() external view returns (uint256) {
return value;
}

function getBalance(address destination) external view returns (uint256) {
return balances[destination];
}

function withdraw() external {
uint256 balance = balances[msg.sender];
require(balance > 0, "Insufficient balance");
balances[msg.sender] = 0;
(bool success,) = msg.sender.call{value: balance}("");
require(success, "Error sending the tokens");
emit Withdraw(msg.sender, value);
}
}
8 changes: 7 additions & 1 deletion integration-test/test/common/constants.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
export const TEST_URL = 'http://localhost:4444'
export const EXTENDED_TIMEOUT = 7200 * 1000
export const TEST_CONTRACT_ABI = [
'function save(address destination) public payable',
'function setValue(uint256 _value) external',
'function retrieveValue() external view returns (uint256)',
'function getBalance(address destination) external view returns (uint256)',
'function withdraw() external'
]
44 changes: 39 additions & 5 deletions integration-test/test/pegin.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { describe, test, beforeAll, expect } from '@jest/globals'
import { type AcceptedQuote, Flyover, FlyoverUtils, type ValidatePeginTransactionOptions, type LiquidityProvider, type Quote } from '@rsksmart/flyover-sdk'
import { BlockchainConnection, assertTruthy } from '@rsksmart/bridges-core-sdk'
import { assertTruthy, ethers, BlockchainReadOnlyConnection } from '@rsksmart/bridges-core-sdk'
import { integrationTestConfig } from '../config'
import { fakeTokenResolver, getUtxosFromMempoolSpace } from './common/utils'
import { Transaction, payments, networks } from 'bitcoinjs-lib'
import { TEST_CONTRACT_ABI } from './common/constants'

describe('Flyover pegin process should', () => {
let flyover: Flyover
Expand All @@ -19,10 +20,7 @@ describe('Flyover pegin process should', () => {
captchaTokenResolver: fakeTokenResolver,
disableChecksum: true
})
const rsk = await BlockchainConnection.createUsingPassphrase(
integrationTestConfig.testMnemonic,
integrationTestConfig.nodeUrl
)
const rsk = await BlockchainReadOnlyConnection.createUsingRpc(integrationTestConfig.nodeUrl)
await flyover.connectToRsk(rsk)
})

Expand Down Expand Up @@ -180,4 +178,40 @@ describe('Flyover pegin process should', () => {
}, options)
expect(result).toBe('')
})

test('get a smart contract interaction quote', async () => {
const smartContractData = new ethers.utils.Interface(TEST_CONTRACT_ABI)
.encodeFunctionData('save', [integrationTestConfig.rskAddress])
flyover.useLiquidityProvider(provider)
const prefixedQuote = await flyover.getQuotes({
callEoaOrContractAddress: integrationTestConfig.testContractAddress,
callContractArguments: smartContractData,
valueToTransfer: integrationTestConfig.peginAmount,
rskRefundAddress: integrationTestConfig.rskAddress
}).then(result => result[0])

const notPrefixedQuote = await flyover.getQuotes({
callEoaOrContractAddress: integrationTestConfig.testContractAddress,
callContractArguments: smartContractData.slice(2),
valueToTransfer: integrationTestConfig.peginAmount,
rskRefundAddress: integrationTestConfig.rskAddress
}).then(result => result[0])

expect(prefixedQuote).not.toBeUndefined()
expect(notPrefixedQuote).not.toBeUndefined()
expect(prefixedQuote?.quote.contractAddr).toBe(integrationTestConfig.testContractAddress)
expect(notPrefixedQuote?.quote.contractAddr).toBe(integrationTestConfig.testContractAddress)
expect(prefixedQuote?.quote.data).toBe(smartContractData.slice(2))
expect(notPrefixedQuote?.quote.data).toBe(smartContractData.slice(2))

/* eslint-disable @typescript-eslint/no-non-null-assertion */
const acceptedPrefixed = await flyover.acceptQuote(prefixedQuote!)
const acceptedNotPrefixed = await flyover.acceptQuote(notPrefixedQuote!)
/* eslint-enable @typescript-eslint/no-non-null-assertion */
expect(acceptedPrefixed.bitcoinDepositAddressHash).not.toBeUndefined()
expect(acceptedNotPrefixed.bitcoinDepositAddressHash).not.toBeUndefined()

console.info('Prefixed quote payment address:', acceptedPrefixed.bitcoinDepositAddressHash)
console.info('Not prefixed quote payment address:', acceptedNotPrefixed.bitcoinDepositAddressHash)
})
})
20 changes: 19 additions & 1 deletion integration-test/test/pegout.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, test, beforeAll, expect } from '@jest/globals'
import { assertTruthy, BlockchainConnection } from '@rsksmart/bridges-core-sdk'
import { assertTruthy, BlockchainConnection, BlockchainReadOnlyConnection } from '@rsksmart/bridges-core-sdk'
import { Flyover, type PegoutQuote, type LiquidityProvider, type AcceptedPegoutQuote, FlyoverUtils } from '@rsksmart/flyover-sdk'
import { integrationTestConfig } from '../config'
import { EXTENDED_TIMEOUT } from './common/constants'
Expand Down Expand Up @@ -96,6 +96,24 @@ describe('Flyover pegout process should', () => {
expect(acceptedQuote.lbcAddress).not.toBeUndefined()
})

test('fail to deposit pegout if connection is readonly', async () => {
const readonlyFlyover = new Flyover({
network: integrationTestConfig.network,
allowInsecureConnections: true,
captchaTokenResolver: fakeTokenResolver,
disableChecksum: true,
rskConnection: await BlockchainReadOnlyConnection.createUsingRpc(integrationTestConfig.nodeUrl)
})
const amount = FlyoverUtils.getQuoteTotal(selectedQuote)
expect.assertions(2)
try {
await readonlyFlyover.depositPegout(selectedQuote, acceptedQuote.signature, amount)
} catch (e: any) {
expect(e.message).toBe('error executing function depositPegout')
expect(e.details.error).toContain('sending a transaction requires a signer')
}
})

test('deposit amount to lbc for accepted quote', async () => {
const txHash = await flyover.depositPegout(selectedQuote, acceptedQuote.signature, FlyoverUtils.getQuoteTotal(selectedQuote))
expect([null, undefined, '']).not.toContain(txHash)
Expand Down
7 changes: 2 additions & 5 deletions integration-test/test/providers.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, test, beforeAll, expect } from '@jest/globals'
import { assertTruthy, BlockchainConnection } from '@rsksmart/bridges-core-sdk'
import { assertTruthy, BlockchainReadOnlyConnection } from '@rsksmart/bridges-core-sdk'
import { Flyover } from '@rsksmart/flyover-sdk'
import { fakeTokenResolver } from './common/utils'
import { integrationTestConfig } from '../config'
Expand All @@ -15,10 +15,7 @@ describe('Flyover SDK should perform the following liquidity provider related op
captchaTokenResolver: fakeTokenResolver,
disableChecksum: true
})
const rsk = await BlockchainConnection.createUsingPassphrase(
integrationTestConfig.testMnemonic,
integrationTestConfig.nodeUrl
)
const rsk = await BlockchainReadOnlyConnection.createUsingRpc(integrationTestConfig.nodeUrl)
await flyover.connectToRsk(rsk)
})

Expand Down
9 changes: 8 additions & 1 deletion integration-test/test/rsk.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, test, expect } from '@jest/globals'
import { Flyover } from '@rsksmart/flyover-sdk'
import ethProvider from 'eth-provider'
import { BlockchainConnection } from '@rsksmart/bridges-core-sdk'
import { BlockchainConnection, BlockchainReadOnlyConnection } from '@rsksmart/bridges-core-sdk'
import { fakeTokenResolver } from './common/utils'
import { integrationTestConfig } from '../config'
import { EXTENDED_TIMEOUT } from './common/constants'
Expand All @@ -26,4 +26,11 @@ describe('Flyover Rsk connection should', () => {
const isConnected = await flyover.isConnected()
expect(isConnected).toBe(true)
}, EXTENDED_TIMEOUT)

test('establish readonly connection', async () => {
const rsk = await BlockchainReadOnlyConnection.createUsingRpc(integrationTestConfig.nodeUrl)
const flyover = new Flyover({ rskConnection: rsk, network: integrationTestConfig.network, captchaTokenResolver: fakeTokenResolver })
const isConnected = await flyover.isConnected()
expect(isConnected).toBe(true)
})
})
7 changes: 2 additions & 5 deletions integration-test/test/user.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, test, beforeAll, expect } from '@jest/globals'
import { assertTruthy, BlockchainConnection } from '@rsksmart/bridges-core-sdk'
import { assertTruthy, BlockchainReadOnlyConnection } from '@rsksmart/bridges-core-sdk'
import { Flyover } from '@rsksmart/flyover-sdk'
import { fakeTokenResolver } from './common/utils'
import { integrationTestConfig } from '../config'
Expand All @@ -12,10 +12,7 @@ describe('Flyover SDK client should', () => {
allowInsecureConnections: true,
captchaTokenResolver: fakeTokenResolver
})
const rsk = await BlockchainConnection.createUsingPassphrase(
integrationTestConfig.testMnemonic,
integrationTestConfig.nodeUrl
)
const rsk = await BlockchainReadOnlyConnection.createUsingRpc(integrationTestConfig.nodeUrl)
await flyover.connectToRsk(rsk)
})

Expand Down
Loading
Loading