Skip to content

Commit

Permalink
#NOISSUE - add support for custodial wallet proxy generation for CELO…
Browse files Browse the repository at this point in the history
… and MATIC
  • Loading branch information
Samuel Sramko committed Oct 22, 2021
1 parent f144266 commit 0940a3f
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 21 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tatumio/tatum",
"version": "1.29.1",
"version": "1.29.2",
"description": "Tatum API client allows browsers and Node.js clients to interact with Tatum API.",
"main": "dist/src/index.js",
"repository": "https://github.com/tatumio/tatum-js",
Expand Down
21 changes: 20 additions & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,28 @@ export const CONTRACT_DECIMALS = {
[Currency.BBCH.toString()]: 18,
}

export const CUSTODIAL_PROXY_ABI = {
'inputs': [
{
'internalType': 'address',
'name': 'owner',
'type': 'address'
},
{
'internalType': 'uint256',
'name': 'count',
'type': 'uint256'
}
],
'name': 'cloneNewWallet',
'outputs': [],
'stateMutability': 'nonpayable',
'type': 'function'
};

export const CELO_BASED_CURRENCIES = [
Currency.CELO.toString(), Currency.CEUR.toString(), Currency.CUSD.toString(),
]
];

export const TRANSFER_METHOD_ABI = {
constant: false,
Expand Down
34 changes: 34 additions & 0 deletions src/model/request/GenerateCustodialAddressBatch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {Type} from 'class-transformer';
import {IsIn, IsNotEmpty, IsNumber, IsOptional, Length, Max, Min} from 'class-validator';
import {Currency} from './Currency';
import {Fee} from './Fee';
import {PrivateKeyOrSignatureId} from './PrivateKeyOrSignatureId';

export class GenerateCustodialAddressBatch extends PrivateKeyOrSignatureId {

@IsNotEmpty()
@IsIn([Currency.MATIC, Currency.CELO])
public chain: Currency;

@IsNumber()
@IsNotEmpty()
@Min(0)
@Max(270)
public batchCount: number;

@IsNotEmpty()
@Length(34, 43)
public owner: string;

@IsOptional()
@Min(0)
public nonce?: number;

@IsOptional()
@Type(() => Fee)
public fee?: Fee;

@IsOptional()
@IsIn([Currency.CELO, Currency.CUSD, Currency.CEUR])
public feeCurrency?: Currency;
}
1 change: 1 addition & 0 deletions src/model/request/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './TransferEthOffchainKMS';
export * from './TransferXlmOffchainKMS';
export * from './TransferXrpOffchainKMS';
export * from './TransferBchBlockchain';
export * from './GenerateCustodialAddressBatch';
export * from './TransferBtcBasedBlockchain';
export * from './TransferErc20';
export * from './TransferFlowCustomTx';
Expand Down
62 changes: 47 additions & 15 deletions src/wallet/custodial.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
ContractType,
Currency,
GenerateCustodialAddress,
GenerateCustodialAddressBatch,
GenerateTronCustodialAddress,
TransferFromCustodialAddress,
TransferFromCustodialAddressBatch,
Expand All @@ -34,7 +35,13 @@ import {
sendEthGenerateCustodialWalletSignedTransaction,
sendTronGenerateCustodialWalletSignedTransaction
} from '../transaction';
import {obtainCustodialAddressType, prepareApproveFromCustodialWallet, prepareBatchTransferFromCustodialWallet, prepareTransferFromCustodialWallet} from './custodial';
import {
generateCustodialWalletBatch,
obtainCustodialAddressType,
prepareApproveFromCustodialWallet,
prepareBatchTransferFromCustodialWallet,
prepareTransferFromCustodialWallet
} from './custodial';

describe('Custodial wallet tests', () => {

Expand Down Expand Up @@ -173,25 +180,50 @@ describe('Custodial wallet tests', () => {
})

it('should deploy 721_1155', () => {
const body = new GenerateCustodialAddress()
body.enableBatchTransactions = false
body.enableFungibleTokens = false
body.enableNonFungibleTokens = true
body.enableSemiFungibleTokens = true
const {abi} = obtainCustodialAddressType(body)
expect(abi).toBe(Custodial_721_1155_TokenWallet.abi)
const body = new GenerateCustodialAddress();
body.enableBatchTransactions = false;
body.enableFungibleTokens = false;
body.enableNonFungibleTokens = true;
body.enableSemiFungibleTokens = true;
const {abi} = obtainCustodialAddressType(body);
expect(abi).toBe(Custodial_721_1155_TokenWallet.abi);
})
})

describe('Deploy batch address', () => {
it('should create on CELO', async () => {
const body = new GenerateCustodialAddressBatch();
body.fromPrivateKey = '0x4874827a55d87f2309c55b835af509e3427aa4d52321eeb49a2b93b5c0f8edfb';
body.chain = Currency.CELO;
body.feeCurrency = Currency.CUSD;
body.batchCount = 200;
body.owner = '0x8cb76aEd9C5e336ef961265c6079C14e9cD3D2eA';
const txData = await generateCustodialWalletBatch(true, body, 'https://alfajores-forno.celo-testnet.org');
expect(txData.txId).toContain('0x');
console.log(txData.txId);
});

it('should create on MATIC', async () => {
const body = new GenerateCustodialAddressBatch();
body.fromPrivateKey = '0x4874827a55d87f2309c55b835af509e3427aa4d52321eeb49a2b93b5c0f8edfb';
body.chain = Currency.MATIC;
body.batchCount = 200;
body.owner = '0x8cb76aEd9C5e336ef961265c6079C14e9cD3D2eA';
const txData = await generateCustodialWalletBatch(true, body);
expect(txData.txId).toContain('0x');
console.log(txData.txId);
});
});

describe('Deploy address', () => {
it('should create on CELO no batch', async () => {
const body = new GenerateCustodialAddress()
body.fromPrivateKey = '0x4874827a55d87f2309c55b835af509e3427aa4d52321eeb49a2b93b5c0f8edfb'
body.chain = Currency.CELO
body.feeCurrency = Currency.CUSD
body.enableFungibleTokens = true
body.enableNonFungibleTokens = true
body.enableSemiFungibleTokens = false
const body = new GenerateCustodialAddress();
body.fromPrivateKey = '0x4874827a55d87f2309c55b835af509e3427aa4d52321eeb49a2b93b5c0f8edfb';
body.chain = Currency.CELO;
body.feeCurrency = Currency.CUSD;
body.enableFungibleTokens = true;
body.enableNonFungibleTokens = true;
body.enableSemiFungibleTokens = false;
body.enableBatchTransactions = false
const txData = await sendCeloGenerateCustodialWalletSignedTransaction(true, body, 'https://alfajores-forno.celo-testnet.org')
expect(txData.txId).toContain('0x')
Expand Down
64 changes: 60 additions & 4 deletions src/wallet/custodial.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import BigNumber from 'bignumber.js';
import {validateBody} from '../connector/tatum';
import {celoBroadcast, polygonBroadcast} from '../blockchain';
import {get, validateBody} from '../connector/tatum';
import {CUSTODIAL_PROXY_ABI} from '../constants';
import {
Custodial_1155_TokenWallet,
Custodial_1155_TokenWalletWithBatch,
Expand All @@ -24,6 +26,7 @@ import {
ContractType,
Currency,
GenerateCustodialAddress,
GenerateCustodialAddressBatch,
GenerateTronCustodialAddress,
SmartContractMethodInvocation,
TransferFromCustodialAddress,
Expand Down Expand Up @@ -114,15 +117,30 @@ export const obtainCustodialAddressType = (body: GenerateCustodialAddress) => {
return {abi, code};
};

const getCustodialFactoryContractAddress = (chain: Currency, testnet: boolean) => {
switch (chain) {
case Currency.CELO:
return testnet ? '0x7f6ECaef0d01De5D464B8c1Ca968b102ABd40Ca1' : '0xb1462fE8E9Cf82c0296022Cca7bEfA3Fd4c12B34';
case Currency.MATIC:
return testnet ? '0x1C129AE4BF1e6E6C9A0E5e567b8e97E2d41A9265' : '0x3485fdba44736859267789ac9c248cc4c1443956';
default:
throw new Error('Unsupported chain.');
}
};

export const getCustodialAddresses = (chain: Currency, txId: string): Promise<string[]> => get(`v3/blockchain/sc/custodial/${chain}/${txId}`);

/**
* Generate new smart contract based custodial wallet. This wallet is able to receive any type of assets, btu transaction costs connected to the withdrawal
* This method is @Deprecated. Use @link{generateCustodialWalletBatch} instead
* Generate new smart contract based custodial wallet. This wallet is able to receive any type of assets, but transaction costs connected to the withdrawal
* of assets is covered by the deployer.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
export const generateCustodialWallet = async (testnet: boolean, body: GenerateCustodialAddress | GenerateTronCustodialAddress, provider?: string) => {
console.log('This method is deprecated. For better gas consumption, use generateCustodialWalletBatch.');
switch (body.chain) {
case Currency.CELO:
return await sendCeloGenerateCustodialWalletSignedTransaction(testnet, body, provider);
Expand All @@ -142,14 +160,16 @@ export const generateCustodialWallet = async (testnet: boolean, body: GenerateCu
};

/**
* Generate new smart contract based custodial wallet. This wallet is able to receive any type of assets, btu transaction costs connected to the withdrawal
* This method is @Deprecated. Use @link{prepareCustodialWalletBatch} instead
* Generate new smart contract based custodial wallet. This wallet is able to receive any type of assets, but transaction costs connected to the withdrawal
* of assets is covered by the deployer.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
export const prepareCustodialWallet = async (testnet: boolean, body: GenerateCustodialAddress | GenerateTronCustodialAddress, provider?: string) => {
console.log('This method is deprecated. For better gas consumption, use prepareCustodialWalletBatch.');
switch (body.chain) {
case Currency.CELO:
return await prepareCeloGenerateCustodialWalletSignedTransaction(testnet, body, provider);
Expand All @@ -167,9 +187,45 @@ export const prepareCustodialWallet = async (testnet: boolean, body: GenerateCus
throw new Error('Unsupported chain');
}
};
/**
* Generate new smart contract based custodial wallet. This wallet is able to receive any type of assets, but transaction costs connected to the withdrawal
* of assets is covered by the deployer.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
export const generateCustodialWalletBatch = async (testnet: boolean, body: GenerateCustodialAddressBatch, provider?: string) => {
const txData = await prepareCustodialWalletBatch(testnet, body, provider);
switch (body.chain) {
case Currency.CELO:
return await celoBroadcast(txData, body.signatureId);
case Currency.MATIC:
return await polygonBroadcast(txData, body.signatureId);
default:
throw new Error('Unsupported chain');
}
};

/**
* Generate new smart contract based custodial wallet. This wallet is able to receive any type of assets, but transaction costs connected to the withdrawal
* of assets is covered by the deployer.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
export const prepareCustodialWalletBatch = async (testnet: boolean, body: GenerateCustodialAddressBatch, provider?: string) => {
await validateBody(body, GenerateCustodialAddressBatch);
const params = [body.owner.trim(), `0x${new BigNumber(body.batchCount).toString(16)}`];
return await helperPrepareSCCall(testnet, {
...body,
contractAddress: getCustodialFactoryContractAddress(body.chain, testnet)
}, GenerateCustodialAddressBatch, 'cloneNewWallet', params, undefined, provider, [CUSTODIAL_PROXY_ABI]);
};

/**
* Generate new smart contract based custodial wallet. This wallet is able to receive any type of assets, btu transaction costs connected to the withdrawal
* Generate new smart contract based custodial wallet. This wallet is able to receive any type of assets, but transaction costs connected to the withdrawal
* of assets is covered by the deployer.
* @param testnet chain to work with
* @param body request data
Expand Down

0 comments on commit 0940a3f

Please sign in to comment.