Skip to content
This repository has been archived by the owner on May 16, 2024. It is now read-only.

Commit

Permalink
CORE-1952 add v2 complete withdrawal (#413)
Browse files Browse the repository at this point in the history
* update OpenAPI generated API client code

* add prepare withdrawal v2 workflow

* fix typo

* update error message

* rename vars

* update

* update

* fix bad refs

* add stark v4 factory

* rename core factory to stark v3

* update

* add v2 complete withdrawal

* update

* add v4 stark contract

* update

* update examples

* update changelog and version

* changelog

* update version and changelog

* update import
  • Loading branch information
kaihirota authored Feb 27, 2024
1 parent 40d042b commit 64cff23
Show file tree
Hide file tree
Showing 11 changed files with 306 additions and 89 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [3.0.0] - 2024-02-26

### Added

- `completeWithdrawal` has been updated to use V2 withdrawal logic for StarkEx V4 contract.
- [BREAKING CHANGE] `completeWithdrawal` now requires `WalletConnection` instead of Eth Signer.


## [2.6.1] - 2024-02-26

### Added
Expand Down
5 changes: 1 addition & 4 deletions examples/completeErc20Withdrawal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@ import { generateWalletConnection } from './libs/walletConnection';

const client = new ImmutableX(Config.SANDBOX);

const starkPublicKey = await walletConnection.starkSigner.getAddress();

const completeWithdrawalResponse = await client.completeWithdrawal(
walletConnection.ethSigner,
starkPublicKey,
walletConnection,
{
type: 'ERC20',
tokenAddress: '',
Expand Down
5 changes: 1 addition & 4 deletions examples/completeEthWithdrawal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@ import { generateWalletConnection } from './libs/walletConnection';

const client = new ImmutableX(Config.SANDBOX);

const starkPublicKey = await walletConnection.starkSigner.getAddress();

const completeWithdrawalResponse = await client.completeWithdrawal(
walletConnection.ethSigner,
starkPublicKey,
walletConnection,
{
type: 'ETH',
},
Expand Down
5 changes: 1 addition & 4 deletions examples/completeNftWithdrawal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@ import { generateWalletConnection } from './libs/walletConnection';

const client = new ImmutableX(Config.SANDBOX);

const starkPublicKey = await walletConnection.starkSigner.getAddress();

const completeWithdrawalResponse = await client.completeWithdrawal(
walletConnection.ethSigner,
starkPublicKey,
walletConnection,
{
type: 'ERC721',
tokenAddress: '',
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@imtbl/core-sdk",
"version": "2.6.1",
"version": "3.0.0",
"description": "Immutable Core SDK",
"main": "dist/index.cjs.js",
"module": "dist/index.es.js",
Expand Down
8 changes: 3 additions & 5 deletions src/ImmutableX.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,19 +592,17 @@ export class ImmutableX {

/**
* Completes a Withdrawal
* @param ethSigner - the L1 signer
* @param starkPublicKey - the Signer address
* @param walletConnection - the pair of L1/L2 signers
* @param token - the token
* @returns a promise that resolves with the transaction
* @throws {@link index.IMXError}
*/
public completeWithdrawal(
ethSigner: EthSigner,
starkPublicKey: string,
walletConnection: WalletConnection,
token: AnyToken,
) {
return this.workflows
.completeWithdrawal(ethSigner, starkPublicKey, token)
.completeWithdrawal(walletConnection, token)
.catch(err => {
throw formatError(err);
});
Expand Down
30 changes: 28 additions & 2 deletions src/workflows/withdrawal/completeERC20Withdrawal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
StarkV3__factory,
Registration,
Registration__factory,
StarkV4__factory,
} from '../../contracts';
import { ERC20Token } from '../../types';
import {
Expand Down Expand Up @@ -55,14 +56,14 @@ async function executeWithdrawERC20(
return signer.sendTransaction(populatedTransaction);
}

export async function completeERC20WithdrawalWorkflow(
export async function completeERC20WithdrawalV1Workflow(
signer: Signer,
starkPublicKey: string,
token: ERC20Token,
encodingApi: EncodingApi,
usersApi: UsersApi,
config: ImmutableXConfiguration,
) {
): Promise<TransactionResponse> {
const assetType = await getEncodeAssetInfo('asset', 'ERC20', encodingApi, {
token_address: token.tokenAddress,
});
Expand Down Expand Up @@ -99,3 +100,28 @@ export async function completeERC20WithdrawalWorkflow(
);
}
}

export async function completeERC20WithdrawalV2Workflow(
signer: Signer,
token: ERC20Token,
encodingApi: EncodingApi,
config: ImmutableXConfiguration,
): Promise<TransactionResponse> {
const assetType = await getEncodeAssetInfo('asset', 'ERC20', encodingApi, {
token_address: token.tokenAddress,
});

const coreContract = StarkV4__factory.connect(
config.ethConfiguration.coreContractAddress,
signer,
);

const ownerKey = await signer.getAddress();

const populatedTransaction = await coreContract.populateTransaction.withdraw(
ownerKey,
assetType.asset_type,
);

return signer.sendTransaction(populatedTransaction);
}
118 changes: 112 additions & 6 deletions src/workflows/withdrawal/completeERC721Withdrawal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
StarkV3__factory,
Registration,
Registration__factory,
StarkV4__factory,
} from '../../contracts';
import * as encUtils from 'enc-utils';
import { ERC721Token } from '../../types';
Expand Down Expand Up @@ -75,7 +76,7 @@ function getMintingBlob(token: MintableERC721Withdrawal): string {
return encUtils.sanitizeHex(encUtils.utf8ToHex(`{${id}}:{${blueprint}}`));
}

async function completeMintableERC721Withdrawal(
async function completeMintableERC721WithdrawalV1(
signer: Signer,
starkPublicKey: string,
token: MintableERC721Withdrawal,
Expand Down Expand Up @@ -173,7 +174,7 @@ async function executeWithdrawERC721(
return signer.sendTransaction(populatedTransaction);
}

async function completeERC721Withdrawal(
async function completeERC721WithdrawalV1(
signer: Signer,
starkPublicKey: string,
token: ERC721Token,
Expand Down Expand Up @@ -221,15 +222,15 @@ async function completeERC721Withdrawal(
}
}

export async function completeERC721WithdrawalWorkflow(
export async function completeERC721WithdrawalV1Workflow(
signer: Signer,
starkPublicKey: string,
token: ERC721Token,
encodingApi: EncodingApi,
mintsApi: MintsApi,
usersApi: UsersApi,
config: ImmutableXConfiguration,
) {
): Promise<TransactionResponse> {
const tokenAddress = token.tokenAddress;
const tokenId = token.tokenId;
return await mintsApi
Expand All @@ -238,7 +239,7 @@ export async function completeERC721WithdrawalWorkflow(
tokenId,
})
.then(mintableToken =>
completeMintableERC721Withdrawal(
completeMintableERC721WithdrawalV1(
signer,
starkPublicKey,
{
Expand All @@ -257,7 +258,7 @@ export async function completeERC721WithdrawalWorkflow(
.catch(error => {
if (error.response?.status === 404) {
// token is already minted on L1
return completeERC721Withdrawal(
return completeERC721WithdrawalV1(
signer,
starkPublicKey,
token,
Expand All @@ -269,3 +270,108 @@ export async function completeERC721WithdrawalWorkflow(
throw error; // unable to recover from any other kind of error
});
}

async function completeMintableERC721WithdrawalV2(
signer: Signer,
ownerKey: string,
token: MintableERC721Withdrawal,
encodingApi: EncodingApi,
config: ImmutableXConfiguration,
) {
const assetType = await getEncodeAssetInfo(
'mintable-asset',
'ERC721',
encodingApi,
{
id: token.data.id,
token_address: token.data.tokenAddress,
...(token.data.blueprint && { blueprint: token.data.blueprint }),
},
);
const mintingBlob = getMintingBlob(token);

const coreContract = StarkV4__factory.connect(
config.ethConfiguration.coreContractAddress,
signer,
);

const populatedTransaction =
await coreContract.populateTransaction.withdrawAndMint(
ownerKey,
assetType.asset_type,
mintingBlob,
);
return signer.sendTransaction(populatedTransaction);
}

async function completeERC721WithdrawalV2(
signer: Signer,
ownerKey: string,
token: ERC721Token,
encodingApi: EncodingApi,
config: ImmutableXConfiguration,
) {
const assetType = await getEncodeAssetInfo('asset', 'ERC721', encodingApi, {
token_id: token.tokenId,
token_address: token.tokenAddress,
});

const coreContract = StarkV4__factory.connect(
config.ethConfiguration.coreContractAddress,
signer,
);

const populatedTransaction =
await coreContract.populateTransaction.withdrawNft(
ownerKey,
assetType.asset_type,
token.tokenId,
);
return signer.sendTransaction(populatedTransaction);
}

export async function completeERC721WithdrawalV2Workflow(
signer: Signer,
ownerKey: string,
token: ERC721Token,
encodingApi: EncodingApi,
mintsApi: MintsApi,
config: ImmutableXConfiguration,
): Promise<TransactionResponse> {
const tokenAddress = token.tokenAddress;
const tokenId = token.tokenId;
return await mintsApi
.getMintableTokenDetailsByClientTokenId({
tokenAddress,
tokenId,
})
.then(mintableToken =>
completeMintableERC721WithdrawalV2(
signer,
ownerKey,
{
type: 'ERC721',
data: {
id: tokenId,
tokenAddress: tokenAddress,
blueprint: mintableToken.data.blueprint,
},
},
encodingApi,
config,
),
)
.catch(error => {
if (error.response?.status === 404) {
// token is already minted on L1
return completeERC721WithdrawalV2(
signer,
ownerKey,
token,
encodingApi,
config,
);
}
throw error; // unable to recover from any other kind of error
});
}
27 changes: 25 additions & 2 deletions src/workflows/withdrawal/completeEthWithdrawal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
StarkV3__factory,
Registration,
Registration__factory,
StarkV4__factory,
} from '../../contracts';
import {
getSignableRegistrationOnchain,
Expand Down Expand Up @@ -54,13 +55,13 @@ async function executeWithdrawEth(
return signer.sendTransaction(populatedTransaction);
}

export async function completeEthWithdrawalWorkflow(
export async function completeEthWithdrawalV1Workflow(
signer: Signer,
starkPublicKey: string,
encodingApi: EncodingApi,
usersApi: UsersApi,
config: ImmutableXConfiguration,
) {
): Promise<TransactionResponse> {
const assetType = await getEncodeAssetInfo('asset', 'ETH', encodingApi);

const coreContract = StarkV3__factory.connect(
Expand Down Expand Up @@ -95,3 +96,25 @@ export async function completeEthWithdrawalWorkflow(
);
}
}

export async function completeEthWithdrawalV2Workflow(
signer: Signer,
encodingApi: EncodingApi,
config: ImmutableXConfiguration,
): Promise<TransactionResponse> {
const assetType = await getEncodeAssetInfo('asset', 'ETH', encodingApi);

const coreContract = StarkV4__factory.connect(
config.ethConfiguration.coreContractAddress,
signer,
);

const ownerKey = await signer.getAddress();

const populatedTransaction = await coreContract.populateTransaction.withdraw(
ownerKey,
assetType.asset_type,
);

return signer.sendTransaction(populatedTransaction);
}
Loading

0 comments on commit 64cff23

Please sign in to comment.