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
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
},
"linter": {
"enabled": true,
"ignore": ["scripts/**"],
"rules": {
"recommended": true,
"correctness": {
Expand Down Expand Up @@ -49,7 +50,6 @@
"ignore": [
".vscode",
".idea",
"scripts/**",
"node_modules/**",
".turbo/**",
"build/**",
Expand Down
2 changes: 1 addition & 1 deletion docker/fuel-core/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

# We should be supporting always the same fuel-core version as the fuels (ts-sdk)
# https://github.com/FuelLabs/fuels-ts/blob/master/internal/fuel-core/VERSION
FROM ghcr.io/fuellabs/fuel-core:v0.40.0
FROM ghcr.io/fuellabs/fuel-core:v0.44.0

# dependencies
ENV DEBIAN_FRONTEND=noninteractive
Expand Down
3 changes: 2 additions & 1 deletion packages/contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"test": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --runInBand --silent",
"build": "tsup",
"build:sway": "pnpm fuels build",
"contracts:start": "ts-node scripts/construct-contracts.ts"
"contracts:start": "dotenv -e .env -- ts-node scripts/construct-contracts.ts",
"contracts:deploy": "dotenv -e .env -- ts-node scripts/deploy.ts"
},
"keywords": [],
"author": "",
Expand Down
61 changes: 45 additions & 16 deletions packages/contracts/scripts/construct-contracts.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
import { getContractId, Manager, Nft, Registry, Resolver } from '../src';
import { Manager, Nft, Registry, Resolver, getContractId } from '../src';
import { logger, setup } from './utils';

const main = async () => {
const { provider, wallet } = await setup();

const managerId = getContractId(provider.url, 'manager');
const resolverId = getContractId(provider.url, 'resolver');
const registryId = getContractId(provider.url, 'registry');
const nftId = getContractId(provider.url, 'nft');

const manager = new Manager(managerId, wallet);
const resolver = new Resolver(resolverId, wallet);
const registry = new Registry(registryId, wallet);
export const constructNft = async (wallet: any, registryId: string) => {
const nftId = getContractId(wallet.provider.url, 'nft');
const nft = new Nft(nftId, wallet);

try {
const { value: nftOwner } = await manager.functions.owner().get();
const { value: nftOwner } = await nft.functions.owner().get();

// @ts-ignore
if (nftOwner === 'Uninitialized') {
const nftConstruct = await nft.functions
.constructor(
{ Address: { bits: wallet.address.toB256() } },
{ ContractId: { bits: registryId } },
{ ContractId: { bits: registryId } }
)
.call();
await nftConstruct.waitForResult();
Expand All @@ -44,6 +35,13 @@ const main = async () => {
}
}

return nftId;
};

export const constructManager = async (wallet: any, registryId: string) => {
const managerId = getContractId(wallet.provider.url, 'manager');
const manager = new Manager(managerId, wallet);

try {
const { value: managerOwner } = await manager.functions.owner().get();

Expand All @@ -52,7 +50,7 @@ const main = async () => {
const managerConstruct = await manager.functions
.constructor(
{ Address: { bits: wallet.address.toB256() } },
{ ContractId: { bits: registryId } },
{ ContractId: { bits: registryId } }
)
.call();
await managerConstruct.waitForResult();
Expand All @@ -74,6 +72,13 @@ const main = async () => {
}
}

return managerId;
};

export const constructResolver = async (wallet: any, managerId: string) => {
const resolverId = getContractId(wallet.provider.url, 'resolver');
const resolver = new Resolver(resolverId, wallet);

try {
const resolverConstruct = await resolver.functions
.constructor({ bits: managerId })
Expand All @@ -88,12 +93,23 @@ const main = async () => {
}
}

return resolverId;
};

export const constructRegistry = async (
wallet: any,
managerId: string,
nftId: string
) => {
const registryId = getContractId(wallet.provider.url, 'registry');
const registry = new Registry(registryId, wallet);

try {
const registryConstruct = await registry.functions
.constructor(
{ bits: wallet.address.toB256() },
{ bits: managerId },
{ bits: nftId },
{ bits: nftId }
)
.call();
await registryConstruct.waitForResult();
Expand All @@ -105,6 +121,19 @@ const main = async () => {
logger.error('Registry construct failed', e);
}
}

return registryId;
};

const main = async () => {
const { provider, wallet } = await setup();

const registryId = getContractId(provider.url, 'registry');

const nftId = await constructNft(wallet, registryId);
const managerId = await constructManager(wallet, registryId);
await constructResolver(wallet, managerId);
await constructRegistry(wallet, managerId, nftId);
};

main()
Expand Down
143 changes: 143 additions & 0 deletions packages/contracts/scripts/deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import {
type Account,
type ContractFactory,
type Provider,
Src14OwnedProxy,
Src14OwnedProxyFactory,
ZeroBytes32,
} from 'fuels';
import {
type Contracts,
ManagerFactory,
NftFactory,
RegistryFactory,
ResolverFactory,
getContractId,
} from '../src';
import { logger, setContractId, setup } from './utils';

type DeployConfig = {
contract: {
name: Contracts;
factory: ContractFactory;
configurableConstants?: Record<any, any>;
};
provider: Provider;
wallet: Account;
};

const deployContractWithProxy = async (config: DeployConfig) => {
const { provider, wallet, contract } = config;

logger.info(`[${contract.name}] Deploying new instance...`);
const { contractId, waitForResult: waitForDeploy } =
await contract.factory.deploy({
configurableConstants: contract.configurableConstants,
});
await waitForDeploy();

logger.info(`[${contract.name}] Checking has proxy instance...`);
const proxyAddress = getContractId(provider.url, contract.name);
const addressType = await provider.getAddressType(
proxyAddress ?? ZeroBytes32
);
const isDeployed = addressType === 'Contract';

if (!isDeployed) {
logger.info(`[${contract.name}] Deploying proxy...`);
const proxyDeployment = await Src14OwnedProxyFactory.deploy(wallet, {
configurableConstants: {
INITIAL_TARGET: { bits: contractId },
INITIAL_OWNER: {
Initialized: { Address: { bits: wallet.address.toB256() } },
},
},
});

const { contract: proxy } = await proxyDeployment.waitForResult();
const { waitForResult } = await proxy.functions.initialize_proxy().call();
await waitForResult();

logger.success(
`Proxy for ${contract.name} deployed! Id: ${proxy.id.toB256()}`
);
const proxyAddress = proxy.id.toB256();
setContractId(provider.url, contract.name, proxyAddress);
return proxy.id.toString();
}

logger.info(`[${contract.name}] Has proxy instance! Setting target...`);
const proxy = new Src14OwnedProxy(proxyAddress, wallet);
const { waitForResult } = await proxy.functions
.set_proxy_target({ bits: contractId })
.call();
await waitForResult();
logger.success(
`[${contract.name}] Target set! Proxy: ${proxy.id.toB256()} Target: ${contractId}`
);
return proxy.id.toString();
};

const deployContract = async (config: DeployConfig) => {
const { provider, contract } = config;

logger.info(`Deploying ${contract.name}...`);
const { contractId, waitForResult: waitForDeploy } =
await contract.factory.deploy({
configurableConstants: contract.configurableConstants,
});
await waitForDeploy();

logger.success(`${contract.name} deployed! Id: ${contractId}`);
setContractId(provider.url, contract.name, contractId);
};

const main = async () => {
const { wallet, provider } = await setup();

await deployContractWithProxy({
wallet,
provider,
contract: {
name: 'registry',
factory: new RegistryFactory(wallet),
},
});

await deployContractWithProxy({
wallet,
provider,
contract: {
name: 'manager',
factory: new ManagerFactory(wallet),
},
});

await deployContract({
wallet,
provider,
contract: {
name: 'resolver',
factory: new ResolverFactory(wallet),
},
});

await deployContract({
wallet,
provider,
contract: {
name: 'nft',
factory: new NftFactory(wallet),
},
});
};

main()
.then(() => {
logger.success('Done!');
process.exit(0);
})
.catch((error) => {
logger.error('Construct failed!', error);
process.exit(1);
});
28 changes: 27 additions & 1 deletion packages/contracts/scripts/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import fs from 'node:fs';
import path from 'node:path';
import dotenv from 'dotenv';
import { Provider, Wallet } from 'fuels';
import { type Contracts, type NetworkKeys, resolveNetwork } from '../src';
import contracts from '../src/artifacts/contracts-fuel.json';

dotenv.config({
path: '../.env',
Expand All @@ -12,6 +16,28 @@ export const logger = {
warn: (...data: any) => console.log(`❌ `, ...data),
};

export const setContractId = <N extends NetworkKeys>(
provider: string,
contract: Contracts,
contractId: string
) => {
const network = resolveNetwork(provider) as N;
if (!contracts[network]) {
contracts[network] = {
manager: '',
registry: '',
resolver: '',
nft: '',
};
}

contracts[network]![contract] = contractId;
fs.writeFileSync(
path.join(__dirname, '..', 'src', './artifacts/contracts-fuel.json'),
JSON.stringify(contracts, null, 2)
);
};

export const requireEnv = (name: string) => {
const value = process.env[name];
if (!value) {
Expand All @@ -32,7 +58,7 @@ export const setup = async () => {
`Setup
Provider: ${providerUrl}
Wallet: ${wallet.address.toB256()}
Balance: ${balance.format()} ETH`,
Balance: ${balance.format()} ETH`
);

return { provider, wallet };
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import contracts from './artifacts/contracts-fuel.json';

export type NetworkKeys = keyof typeof contracts;
type ContractKeys<N extends NetworkKeys> = keyof (typeof contracts)[N];
export type Contracts = 'manager' | 'registry' | 'resolver' | 'nft';

const DEFAULT_NETWORK: NetworkKeys = 'testnet';

Expand All @@ -23,7 +23,7 @@ export const resolveNetwork = (provider: string) => {

export const getContractId = <N extends NetworkKeys>(
provider: string,
contract: ContractKeys<N>
contract: Contracts
) => {
const network = resolveNetwork(provider) as N;
return contracts[network]?.[contract];
Expand Down
Loading