Skip to content

chore: switch default from v5 to v6 #577

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 29, 2025
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
10 changes: 5 additions & 5 deletions .github/actions/prepare/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ runs:
- name: Download node artifact
uses: actions/download-artifact@v4
with:
name: substrate-contracts-node
name: ink-node
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CI needs to run the ink-node for testing ink! v6 contracts

path: ./

- name: Start local node
shell: bash
run: |
tar -xvzf substrate-contracts-node-linux.tar.gz
cd substrate-contracts-node-linux/
chmod +x ./substrate-contracts-node
./substrate-contracts-node --dev &
tar -xvzf ink-node-linux.tar.gz
cd ink-node-linux/
chmod +x ./ink-node
./ink-node --dev &
6 changes: 3 additions & 3 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- run: |
curl -L "https://github.com/paritytech/substrate-contracts-node/releases/latest/download/substrate-contracts-node-linux.tar.gz" -O
curl -L "https://github.com/use-ink/ink-node/releases/latest/download/ink-node-linux.tar.gz" -O
ls -lash
- name: Save node artifact
uses: actions/upload-artifact@v4
with:
name: substrate-contracts-node
name: ink-node
if-no-files-found: error
path: substrate-contracts-node-linux.tar.gz
path: ink-node-linux.tar.gz

ui-chrome-tests:
timeout-minutes: 15
Expand Down
48 changes: 42 additions & 6 deletions cypress/e2e/contracts/erc20.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,31 +53,67 @@ describe('ERC20 Contract ', () => {

it(`transfers ${transferValue} Units to another account`, () => {
selectMessage('transfer', 3);
cy.get('.form-field.to').find('.dropdown').click().find('.dropdown__option').eq(3).click();
cy.get('.form-field.value').find('input[type="number"]').eq(0).type(`${transferValue}`);
cy.get('.form-field.to')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In all unit tests the main update was the way to select an address, before it was a dropdown to pick Alice/Bob, now we need to type the H160 address

.find("input[type='text']")
.clear()
.type('0x60afa252b554aabc4b3253ca2be60dc1d536ec10')
.should('have.value', '0x60afa252b554aabc4b3253ca2be60dc1d536ec10');
cy.get('.form-field.value').find('input[type="number"]').type(`${transferValue}`);
assertCall();
selectMessage('balanceOf', 1);

cy.get('.form-field.owner')
.find("input[type='text']")
.clear()
.type('0x9621dde636de098b43efb0fa9b61facfe328f99d')
.should('have.value', '0x9621dde636de098b43efb0fa9b61facfe328f99d');
assertReturnValue('balanceOf', `${initialSupply - transferValue}`);
});

it(`successfully approves allowance`, () => {
selectMessage('approve', 4);
cy.get('.form-field.spender').find('.dropdown').click().find('.dropdown__option').eq(2).click();
cy.get('.form-field.spender')
.find("input[type='text']")
.clear()
.type('0x41dccbd49b26c50d34355ed86ff0fa9e489d1e01')
.should('have.value', '0x41dccbd49b26c50d34355ed86ff0fa9e489d1e01');
cy.get('.form-field.value').find('input[type="number"]').type(`${allowance}`);
assertCall();
selectMessage('allowance', 2);
cy.get('.form-field.spender').find('.dropdown').click().find('.dropdown__option').eq(2).click();
cy.get('.form-field.owner')
.find("input[type='text']")
.clear()
.type('0x9621dde636de098b43efb0fa9b61facfe328f99d')
.should('have.value', '0x9621dde636de098b43efb0fa9b61facfe328f99d');
cy.get('.form-field.spender')
.find("input[type='text']")
.clear()
.type('0x41dccbd49b26c50d34355ed86ff0fa9e489d1e01')
.should('have.value', '0x41dccbd49b26c50d34355ed86ff0fa9e489d1e01');
assertReturnValue('allowance', `${allowance}`);
});

it(`transfers ${transferValue} on behalf of alice`, () => {
cy.get('.form-field.caller').click().find('.dropdown__option').eq(2).click();
selectMessage('transferFrom', 5);
cy.get('.form-field.to').find('.dropdown').click().find('.dropdown__option').eq(2).click();
cy.get('.form-field.from')
.find("input[type='text']")
.clear()
.type('0x9621dde636de098b43efb0fa9b61facfe328f99d')
.should('have.value', '0x9621dde636de098b43efb0fa9b61facfe328f99d');
cy.get('.form-field.to')
.find("input[type='text']")
.clear()
.type('0x41dccbd49b26c50d34355ed86ff0fa9e489d1e01')
.should('have.value', '0x41dccbd49b26c50d34355ed86ff0fa9e489d1e01');
cy.get('.form-field.value').find('input[type="number"]').type(`${transferValue}`);
assertCall();
selectMessage('balanceOf', 1);
cy.get('.form-field.owner').find('.dropdown').click().find('.dropdown__option').eq(2).click();
cy.get('.form-field.owner')
.find("input[type='text']")
.clear()
.type('0x41dccbd49b26c50d34355ed86ff0fa9e489d1e01')
.should('have.value', '0x41dccbd49b26c50d34355ed86ff0fa9e489d1e01');
assertReturnValue('balanceOf', `${transferValue}`);
});
});
15 changes: 8 additions & 7 deletions cypress/e2e/contracts/mother.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
assertMoveToStep3,
assertContractRedirect,
assertInstantiate,
selectAccount,
} from '../../support/util';

describe('Mother Contract ', () => {
Expand Down Expand Up @@ -42,8 +41,8 @@ describe('Mother Contract ', () => {

it('displays `bids: Auction` input correctly ', () => {
cy.get('.form-field.bids').within(() => {
cy.contains('Vec<Vec<Option<(AccountId,u128)>>>').should('be.visible');
cy.contains('Vec<Option<(AccountId,u128)>>').should('be.visible');
cy.contains('Vec<Vec<Option<(H160,u128)>>>').should('be.visible');
cy.contains('Vec<Option<(H160,u128)>>').should('be.visible');
cy.get('.vector-field-1').should('have.lengthOf', 1);
cy.get('.vector-field-2')
.should('have.lengthOf', 1)
Expand All @@ -68,19 +67,21 @@ describe('Mother Contract ', () => {
cy.get('.vector-field-2').should('have.lengthOf', 3);
});
});
it('displays inputs for `Option<(AccountId,u128)` and sets values', () => {
it('displays inputs for `Option<(H160,u128)` and sets values', () => {
cy.get('.form-field.bids .vector-field-2')
.first()
.each($el => {
cy.wrap($el)
.scrollIntoView()
.within(() => {
cy.get('[data-cy="switch-button"]').click();
cy.contains('0: AccountId').should('be.visible');
cy.get('.dropdown').should('have.lengthOf', 1);
cy.contains('0: H160').should('be.visible');
cy.get("input[type='text']")
.clear()
.type('0x41dccbd49b26c50d34355ed86ff0fa9e489d1e01')
.should('have.value', '0x41dccbd49b26c50d34355ed86ff0fa9e489d1e01');
cy.contains('1: u128').should('be.visible');
cy.get("input[type='number']").should('have.lengthOf', 1).type('99999');
selectAccount('bob', 2);
});
});
});
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/contracts/storage_types.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe('Storage Types Contract', () => {
'getOptionNone',
'getResultOk',
'getResultError',
'getPanic',
//'getPanic',
].forEach((message, index) => {
it(`DryRun ${message}`, () => {
cy.get('.form-field.caller').click().find('.dropdown__option').eq(2).click();
Expand Down
20 changes: 12 additions & 8 deletions cypress/e2e/instantiateDryRun.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
// SPDX-License-Identifier: GPL-3.0-only
import { beforeAllContracts, assertUpload, assertMoveToStep2 } from '../support/util';

describe('Instantiate dry run', () => {
before(() => {
beforeAllContracts();
describe('Instantiate dry run', async () => {
before(async () => {
await beforeAllContracts();
});

it('multisig contract uploads', () => {
Expand All @@ -18,11 +18,15 @@ describe('Instantiate dry run', () => {
it('displays dry run error and debug message', () => {
// initial multisig dry run is expected to return an error because requirement input value = 0
cy.get('[data-cy="dry-run-result"]').within(() => {
cy.contains('ContractTrapped').should('be.visible');
cy.contains('Contract trapped during execution.').should('be.visible');
cy.contains(
"panicked at 'assertion failed: 0 < requirement && requirement <= owners && owners <= MAX_OWNERS",
).should('be.visible');
cy.contains('Contract reverted! The instantiation will not be successful.').should(
'be.visible',
);
// TODO: Not appearing in v6 for a contract built in debug mode.
//cy.contains('ContractTrapped').should('be.visible');
//cy.contains('Contract trapped during execution.').should('be.visible');
// cy.contains(
// "panicked at 'assertion failed: 0 < requirement && requirement <= owners && owners <= MAX_OWNERS",
// ).should('be.visible');
});
});

Expand Down
9 changes: 8 additions & 1 deletion cypress/e2e/updateMetadata.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@
import { beforeAllContracts, deploy } from '../support/util';

describe('Update contract metadata', () => {
const messages1 = ['new', 'newDefault', 'failedNew', 'echoAuction', 'revertOrTrap', 'debugLog'];
const messages1 = [
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'new',
'newDefault',
'failedNew',
'echoAuction',
'revertOrTrap',
'mutHelloWorld',
];
const messages2 = ['new', 'newDefault', 'flip', 'get'];

before(() => {
Expand Down
1 change: 1 addition & 0 deletions cypress/fixtures/4.2.0/erc20.contract

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cypress/fixtures/4.2.0/flipper.contract

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cypress/fixtures/4.2.0/mother.contract

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cypress/fixtures/4.2.0/multisig.contract

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cypress/fixtures/4.2.0/storage_types.contract

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cypress/fixtures/erc20.contract

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cypress/fixtures/flipper.contract

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cypress/fixtures/mother.contract

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cypress/fixtures/multisig.contract

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cypress/fixtures/storage_types.contract

Large diffs are not rendered by default.

20 changes: 17 additions & 3 deletions cypress/support/util.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
import { WsProvider, ApiPromise, Keyring } from '@polkadot/api';

const timeout = 25000;

export function beforeAllContracts() {
export async function beforeAllContracts() {
Copy link
Contributor Author

@AlexD10S AlexD10S Jul 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to map the accounts Alice and Bob

const wsProvider = new WsProvider('ws://127.0.0.1:9944');
const api = new ApiPromise({ provider: wsProvider });
api.on('connected', async () => {
await api.isReady;

const keyring = new Keyring({ type: 'sr25519' });
const alice = keyring.addFromUri('//Alice', { name: 'Alice' });
const bob = keyring.addFromUri('//Bob', { name: 'Bob' });
await api.tx.revive.mapAccount().signAndSend(alice);
await api.tx.revive.mapAccount().signAndSend(bob);
});

cy.visit(`/instantiate/?rpc=ws://127.0.0.1:9944`);
cy.get('[data-cy="spinner"]').should('not.exist', {
timeout,
Expand Down Expand Up @@ -43,7 +57,7 @@ export function assertInstantiate() {
cy.get('[data-cy="submit-btn"]').click();
cy.get('[data-cy="transaction-complete"]', { timeout })
.should('exist')
.and('contain', 'contracts:Instantiated')
.and('contain', 'revive:Instantiated')
.and('contain', 'system:NewAccount')
.and('contain', 'balances:Transfer')
.and('contain', 'balances:Withdraw')
Expand All @@ -57,7 +71,7 @@ export function assertCall() {
cy.get('[data-cy="transaction-complete"]', { timeout })
.should('exist')
.and('contain', 'system:ExtrinsicSuccess')
.and('contain', 'contracts:ContractEmitted');
.and('contain', 'revive:ContractEmitted');
cy.get('[data-cy="dismiss-notification"]').click();
}

Expand Down
7 changes: 2 additions & 5 deletions snapshots.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// Copyright 2022-2024 use-ink/contracts-ui authors & contributors
// SPDX-License-Identifier: GPL-3.0-only

module.exports = {
__version: '13.13.3',
'Storage Types Contract': {
Expand All @@ -17,13 +14,13 @@ module.exports = {
1: "<code>{\n accountIdValue: '5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM',\n balanceValueMax: '340,282,366,920,938,463,463,374,607,431,768,211,455',\n balanceValueMin: '0',\n hashValue:\n '0x0000000000000000000000000000000000000000000000000000000000000000',\n }</code>",
},
'DryRun getPrimitiveTypes': {
1: "<code>{\n boolValue: true,\n enumWithoutValues: 'A',\n enumWithValues: {\n ThreeValues: [\n '1',\n '2',\n '3',\n ],\n },\n arrayValue: [\n '3',\n '2',\n '1',\n ],\n tupleValue: [\n '7',\n '8',\n ],\n }</code>",
1: "<code>{\n boolValue: true,\n enumWithoutValues: 'A',\n enumWithValues: {\n ThreeValues: [\n '1',\n '2',\n '3',\n ],\n },\n arrayValue: [\n '3',\n '2',\n '1',\n ],\n tupleValue: [\n '7',\n '8',\n ],\n tupleTripletValue: [\n '-123',\n '0',\n '123',\n ],\n }</code>",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

},
'DryRun getOptionNone': {
1: '<code>null</code>',
},
'DryRun getResultError': {
1: "<code>{\n ErrorWithMessage: 'This is the Error Message.',\n }</code>",
1: '<code>EmptyError</code>',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

},
'DryRun getPanic': {
1: '<code>ContractTrapped</code>',
Expand Down
5 changes: 4 additions & 1 deletion src/lib/callOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function decodeStorageDeposit(
export function getPredictedCharge(dryRun: UIStorageDeposit) {
return dryRun.type === 'charge'
? !dryRun.value?.eq(BN_ZERO)
? dryRun.value ?? null
? (dryRun.value ?? null)
: null
: null;
}
Expand Down Expand Up @@ -63,6 +63,9 @@ export function transformUserInput(
if (type === 'Balance') {
return registry.createType('Balance', value);
}
if (type === 'U256') {
return registry.createType('U256', value);
}

return value;
});
Expand Down
1 change: 1 addition & 0 deletions src/ui/components/form/findComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export function findComponent(
return AddressSelect;

case 'Balance':
case 'U256':
return InputBalance;

case 'Hash':
Expand Down
4 changes: 2 additions & 2 deletions src/ui/contexts/VersionContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface VersionSupported {
const VersionContext = createContext<VersionSupported | undefined>(undefined);

export const VersionContextProvider = ({ children }: React.PropsWithChildren) => {
const [version, setVersion] = useLocalStorage<InkVersion>(LOCAL_STORAGE_KEY.VERSION, 'v5');
const [version, setVersion] = useLocalStorage<InkVersion>(LOCAL_STORAGE_KEY.VERSION, 'v6');

useEffect(() => setVersion(version), [version]);

Expand All @@ -33,4 +33,4 @@ export const useVersion = () => {
};

export const getVersion = () =>
(localStorage.getItem(LOCAL_STORAGE_KEY.VERSION) as InkVersion | null) || 'v5';
(localStorage.getItem(LOCAL_STORAGE_KEY.VERSION) as InkVersion | null) || 'v6';
8 changes: 4 additions & 4 deletions src/ui/layout/sidebar/VersionSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ export function VersionSelect() {
const { version, setVersion } = useVersion();
const dropdownOptions = [
{
label: 'ink! v5 (default)',
value: 'v5',
label: 'ink! v6 (default)',
value: 'v6',
},
{
label: 'ink! v6',
value: 'v6',
label: 'ink! v5',
value: 'v5',
},
];
return (
Expand Down